【问题标题】:sprintf with struct array field - gets segmentation fault具有结构数组字段的 sprintf - 出现分段错误
【发布时间】:2017-01-28 12:54:00
【问题描述】:

这个想法是将文本信息消息格式化为模块内的结构。 尝试使用 (cf module.c) 定义消息时,它就像一个魅力:

/*this works*/
module_text3.info_text[0] = "toto[0]";
module_text3.info_text[1] = "toto[1]";

但是在使用 sprintf 时,我遇到了分段错误(cf module.c):

/*this gives segmentation fault*/
for(cpt=0; cpt < 2; cpt++)
{
  sprintf(module_text3.info_text[cpt], "info[%u]", cpt);
}

3 个不同的文件:main.c、module.h 和 module.c

/*main.c*/
/*gcc -o test main.c module.c*/
#include <stdio.h>
#include "module.h"

int main(int argc, char **argv)
{
  int i;
  struct message3 *ptext3 = moduleFcn3();

  for (i= 0; i < ptext3->info_nb; i++)
  {
    printf("ptext3->info_text[%u]: %s\n", i, ptext3->info_text[i]);
  }
  printf("ptext3->error_text: %s\n", ptext3->error_text);
  printf("ptext3->id: %u\n", ptext3->id);
  printf("ptext3->info_nb: %u\n", ptext3->info_nb);
  printf("ptext3->info_nb_max: %u\n", ptext3->info_nb_max);

  return 0;
}
/*------------------------------------------------------*/
/*module.h*/

#define NB_LINE_MAX 10
struct message3
{
  char *info_text[NB_LINE_MAX]; /*a few info lines.*/
  char *error_text; /*only one line for error.*/
  int id;
  int info_nb_max;
  int info_nb;
};

extern struct message3* moduleFcn3(void);

/*------------------------------------------------------*/
/*module.c*/
#include <stdio.h>
#include "module.h"

/*static is in "Stack".*/
static struct message3 module_text3;

struct message3* moduleFcn3(void)
{
  int cpt = 0;
  struct message3 *ptext;

  /*this gives segmentation fault*/
  for(cpt=0; cpt < 2; cpt++)
  {
    sprintf(module_text3.info_text[cpt], "info[%u]", cpt);
  }

  /*this works*/
//  module_text3.info_text[0] = "toto[0]";
//  module_text3.info_text[1] = "toto[1]";
//  cpt = 2;

  module_text3.error_text = "This is error";
  module_text3.id = 4;
  module_text3.info_nb_max = NB_LINE_MAX;
  module_text3.info_nb = cpt;

  ptext = &module_text3;

  return ptext;
}

对于如何格式化我的信息消息(使用我们不使用 sprintf)的任何建议,我将不胜感激。 谢谢,

【问题讨论】:

  • char *info_text[];char *error_text; 中的指针不指向任何东西,因此 sprintf 将写入随机位置。

标签: c


【解决方案1】:

您没有为info_text 字段中的字符串分配空间。最简单的做法是更改struct

/*module.h*/

#define NB_LINE_MAX 10
#define INFO_MAX 25

struct message3
{
  char info_text[NB_LINE_MAX][INFO_MAX]; /*a few info lines.*/
  char *error_text; /*only one line for error.*/
  int id;
  int info_nb_max;
  int info_nb;
};

extern struct message3* moduleFcn3(void);

【讨论】:

    【解决方案2】:

    您没有为 info_text 字符串分配任何内存。你要么必须先使用malloc(),或者如果你的C库支持它(GNU支持),使用asprintf()而不是sprintf()让它分配足够的内存来为你保存整个输出字符串:

    for(cpt = 0; cpt < 2; cpt++)
      asprintf(&module_text3.info[cpt], "info[%u]", cpt);
    

    别忘了你也必须在某个时候再次释放内存。

    以下行起作用的原因:

    module_text3.info_text[0] = "toto[0]";
    

    编译器是否确保字符串"toto[0]" 存储在内存中的某个位置,而您只需使指针module_text3.info_text[0] 指向该字符串。

    【讨论】:

    • 谢谢你们。解决了。 :-)
    猜你喜欢
    • 2021-06-09
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    相关资源
    最近更新 更多