malloc()在free()之后重用内存位置,导致碎片(?)

时间:2014-10-18 21:49:46

标签: c memory-management malloc free

好吧,我已经付出了很多努力,在这里看了很多问题,但我无法深究这一点。希望你能在这里解决我的问题!

int main(int argc, char *argv[]){

  char read[50]; 
  char *string[10];

  while(1){

    fgets(read,sizeof read, stdin);

    int t = 0; //ticks whenever a non-whitespace char is read 
    int pos = 0; //keeps track of position in string array 
    int i;
    int j;

    for(i = 0; i < sizeof read; i++){
      if(isspace(read[i]) && t != 0){
        string[pos] = malloc((t+1) * (sizeof(char)));
//      int z;
//      for(z = 0; z < sizeof string[pos]; z++){
//        string[pos][z] = '\0';
//      }
        for(j = 0; j < t; j++){
          string[pos][j] = read[i-(t-j)];
        }
        t = 0;
        pos++;
      }
      else if(!isspace(input[i])) t++;
    }

    int k;
    for(k = 0; k < pos; k++){
      printf("%i: %s\n",k,string[k]);
      free(string[k]);
    }
  }
}

我正在尝试编写一个程序,该程序将读取用户的一个句子,然后将其分解为组成单词,每个单词都存储在自己的char数组中。

我使用malloc()来分配足够的内存以适应每个单词,在使用后释放它。

第一次运行很好,但是在后续循环中,短于5个字符的单词(并且只有输入多个单词,用空格分隔)才会正确显示,并附加随机的额外字符/符号。

这可能是因为malloc使用了释放的内存并不是空的吗?如果是这种情况,我应该如何正确使用malloc?

我发现补救的唯一方法就是使用我已经注释掉的代码。它使用\ 0填充新分配的char数组。

谢谢!

示例输出:

input words(0): we we we   
0: we
1: we
2: we

input words(1): we we we 
0: we�
1: we�
2: we

2 个答案:

答案 0 :(得分:6)

你有两个问题:

1)您在条件中使用sizeof read

for(i = 0; i < sizeof read; i++){

如果输入行与sizeof read一样长,该怎么办?你应该在这里使用strlen(read)

2)当您为字符串分配足够的内存时,您不会将它们终止。您可以calloc()将分配的整个内存清零。因为,您正在写入它们,我更倾向于使用malloc()而不是毫无疑问地使用calloc()将其置零,并在循环之后使用0终止字符串:

    for(j = 0; j < t; j++){
      string[pos][j] = read[i-(t-j)];
    }
    string[pos][j] = 0; // 0 terminates the string.

P.S。:sizeof(char)始终为1。

答案 1 :(得分:1)

你永远不应该假设malloc给你的记忆是零。

所有(c风格)字符串应该以值0的尾随字符结尾,如果你不这样做,你得到的是未定义的行为。

在未定义行为的领域中,结果是未定义的!因为编译器可以自由地做它喜欢的事情。

避免未定义的行为。