【问题标题】:Segmentation Fault Using strcat()使用 strcat() 的分段错误
【发布时间】:2015-03-08 19:53:47
【问题描述】:

在下面的代码中,我的 strcat 出现分段错误:

csv* lines_into_csv(int m,char* array[LINES_MAX][COLUMNS]){
   char *first_string, *final_string;
   first_string = (char*)calloc(400,sizeof(char));
   final_string = (char*)calloc(400,sizeof(char));
   csv *earthquake = malloc(sizeof(csv)*LINES_MAX);
   int n, j;

   for(j = 0; j < m; j++){
     for(n = 0; n < COLUMNS; n++ ){
       if (array[j][n] != NULL) {
         if(n < 4){
           strcat(first_string, array[j][n]);
        }
        else if(n == 4){

          earthquake[j].mag = atof(array[j][n]);
        }
        else {

          strcat(final_string, array[j][n]);
        }
       }
     }
     earthquake[j].start_of_line = (char*)calloc(200,sizeof(char));
     earthquake[j].end_of_line = (char*)calloc(200,sizeof(char));
     earthquake[j].start_of_line = strdup(first_string);
     earthquake[j].end_of_line = strdup(final_string);
     free(first_string);free(final_string);
   }


   return earthquake;
}

csv 类型结构由两个 char* 和一个浮点数组成,浮点数是我对文件进行排序的数字。

【问题讨论】:

  • strcat(first_string, tmp); - 你还没有初始化 first_string 这不是由 malloc() 完成的,strcat() 期望找到一个 nul 终止符。如果它在first_string 中找不到它,它会一直在内存中翻找直到找到,那么谁知道它将把你的另一个字符串复制到哪里呢? final_string 和其他人也一样,因为你 malloc() 加载了很多东西,然后在不初始化任何东西的情况下继续使用它。
  • 这可能是......你有什么建议解决它?
  • 旁注:sizeof(char*) 完全是多余的。你应该使用sizeof(char),或者简单地使用1(因为这是char的大小根据定义)。
  • 顺便说一下,strcat 期望两个指向 null-terminated 字符串的指针作为参数。您使用指向有效内存段的参数调用此函数,但这些段未使用以空值结尾的数据进行初始化。这会产生未定义的行为。
  • 我的第二条评论(关于您没有将空终止字符串传递给strcat)对于手头的问题更为重要。

标签: c string segmentation-fault strcat


【解决方案1】:

这里有代码

csv *earthquake = malloc(sizeof(csv*)*LINES_MAX);

您被分配了一个指向 csv 结构的指针数组,但您似乎假设您可以在此处访问 struct csv 的对象:

earthquake->start_of_line = (char*)calloc(200,sizeof(char));
earthquake->end_of_line = (char*)calloc(200,sizeof(char));

你可能是说

csv *earthquake = malloc(sizeof(csv)*LINES_MAX); 

编辑:

检查参数中的长度不超过您分配的长度。还要确保 in-strings 正确地以 0 结尾。

【讨论】:

  • 是的,先生!我的意思是……但是它仍然没有解决我的strcat() 问题
  • 检查过你的字符串长度吗?没有。
【解决方案2】:

您对strcat() 的使用存在问题,因为您没有初始化任何用作目标的字符串。

strcat(first_string, tmp);
...
strcat(final_string, tmp);

strcat() 期望找到一个 nul 终止符来追加下一个字符串。如果它没有找到一个,它会一直在内存中翻找直到找到,那么谁知道它将把你的另一个字符串复制到哪里呢?

一种解决方案是使用calloc()0 写入它分配的内存。

还有另一个问题,内存泄漏。您已在此处分配内存 - 但仅用于第一个数组元素。

earthquake->start_of_line = malloc( 100*sizeof(char*));
earthquake->end_of_line = malloc( 200*sizeof(char*));

这会在你做完之后很快导致内存泄漏

earthquake[j].start_of_line = strdup(first_string);
earthquake[j].end_of_line = strdup(final_string);

您应该知道strdup() 分配了更多内存并返回其指针,然后您会覆盖malloc() 返回的原始指针,因此无法释放该内存,因为您不再拥有指针。

转到您用于dup() 的函数参数array[][],它是初始化的还是随机的?

【讨论】:

  • 抱歉,这是错误的。 stardup 或我对结构的初始化没有错误... calloc 已按建议实施,但没有解决分段错误。
  • 这些字符串在我运行以打印所有值的另一个函数中的工作方式也相同
  • 是的,我删除了那部分,但内存泄漏仍然存在,因为你用earthquake[j].start_of_line = ...(和end_of_line)覆盖了earthquake-&gt;start_of_line=...(用于earthquake[0])。
  • 这与strcat() 没有任何关系。它会给我strdup() 上的错误,这不是...
  • 而且,我不明白你为什么说我的回答是在调用strcat() 之前不初始化字符串内存是错误的,@barakmanos 对此进行了独立评论
猜你喜欢
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2020-10-05
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多