【问题标题】:Dynamic 2D array crashes动态二维数组崩溃
【发布时间】:2015-06-05 12:53:59
【问题描述】:

我正在从一个文件中读取(每行包含 1 个单词)并将每一行放入一个数组中。它在即将关闭文件时崩溃(* glibc检测到* proj:损坏的双链表:0x0000000002139240 ***)。除了第一个元素之外的所有内容都被正确复制(第一个元素应该是“你好吗”,但实际上是“0”)。非常感谢您对此提供任何帮助。

int i = -1;
int numb;
int wsize; 
while (fgets(word,30,file)!=NULL)
{
    if (i==-1)
    {
         if(word[strlen(word)-1]=='\n')
         {
             word[strlen(word)-1] = 0;
         }
         numb = atoi(word);
         ptr = malloc(sizeof(char*)*numb);
    }
    else
    {
        if(word[strlen(word)-1]=='\n')
        {
             word[strlen(word)-1] = 0;
        }
        wsize = strlen(word);
        ptr[i] = malloc(sizeof(char*)*wsize);
        strncpy(ptr[i],word,strlen(word));
        size++;
     }
     i++;
}
int j=0;
while(j<16)     //prints to see if they were copied corectly
{               //ptr[0] was the only one that did not copy corectly
    printf("%s\n",ptr[j]);       
    j++;
}
fclose(file);
printf("test\n"); //was never printed so I assume it crashes at fclose()
return 1;

【问题讨论】:

  • 在退出程序之前,代码需要释放所有那些 malloc 的区域。否则会产生一系列内存泄漏。虽然程序的退出将(可悲地)释放所有分配的内存,但最好在其自身之后进行代码清理,特别是当程序变得更大、运行时间更长并且有越来越多的分配内存要释放时跨度>

标签: c arrays malloc


【解决方案1】:

ptr[i] = malloc(sizeof(char*)*wsize); 行错误,原因有二:

  1. 应该是sizeof(char),而不是sizeof(char*)(或者直接省略这个,因为sizeof(char)在定义上等于1)

  2. 如果要存储长度为wsize的字符串,需要分配wsize+1字节

编辑——更多问题:

  1. size++; 行的用途是什么?你是说wsize++;吗?

  2. while(j&lt;16) 中的数字 16 来自哪里?我建议你改用while(j&lt;i)

  3. 如果main() 返回一个非零值,这表示发生了错误。将此更改为 return 0;,除非您有充分的理由返回其他值。

还有一个:

  1. 我刚刚注意到您使用的是strncpy()。这不会在字符串末尾添加终止 '\0' 字节,因为您已要求它使用不超过 wsize 字节的长度复制长度为 wsize 的字符串。将此行更改为strcpy(ptr[i],word);,它应该可以工作。

完成此操作后,您需要从代码中删除所有潜在的缓冲区溢出。 (有很多。)

【讨论】:

  • Size 是 ptr 的总大小,是一个通过引用传递给这个函数的变量。 Wsize 是从行中取出的当前单词的大小。测试时我使用了 16 个因为我知道有 16 个单词。修复此错误后,此错误将被删除。
  • 感谢您到目前为止的帮助,但我如何判断潜在的缓冲区溢出在哪里?
  • @npzap 如果您知道有 16 个单词,为什么还要费心将单词数存储在文件顶部?显然,如果numb iz 为零,您的程序可能会崩溃,因为它仍然会尝试以文字形式读取,直到到达 EOF。不太明显的是,如果numb = (INT_MAX + 1) / sizeof(char*) 由于malloc() 语句中的算术溢出,它也会崩溃。如果文件中的字符串少于顶部声明的数量,那么您的 printf() 调用将取消引用未分配的指针并导致分段错误。
  • 我知道在我自己的测试中有 16 个单词,这必须针对任意数量的字符串。总是会有顶部的数字声明的数字或单词。但是感谢有关 malloc 和 numb 的输入,我意识到我使用 numb 错误并找到了解决方案。
猜你喜欢
  • 2015-01-28
  • 2019-08-11
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多