0

忍受我。我已经 8 年没有用 c 编码了,我完全困惑为什么我的字符串操作不起作用。我正在编写一个永远循环的程序。在循环中,我初始化了两个 char 指针,每个指针都传递给一个将文本添加到 char 指针(数组)的函数。函数完成后,我打印 char 指针并释放两个 char 指针。但是程序在 7 次迭代后终止,并出现以下错误消息

* 检测到 glibc * ./test: 双重释放或损坏 (fasttop): 0x0804a168 ***

#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include stdio.h
#include stdlib.h
#include errno.h
#include time.h

char *SEPERATOR = "|";

void getEvent (char* results);
void getTimeStamp(char* timeStamp, int timeStampSize);
void stringAppend(char* str1, char* str2);

int main (int argc, char *argv[])
{
  int i = 0; 
  while(1)
  { 
    i++;
    printf("%i", i);    

    char* events= realloc(NULL, 1); 
    events[0] = '\0';
    getEvent(events);

    char* timestamp= realloc(NULL, 20);
    timestamp[0] = '\0';
    getTimeStamp(timestamp, 20);

    printf("%s", events);
    printf("timestamp: %s\n", timestamp);

    free(events);
    free(timestamp);
  } 
}

void getEvent (char* results)
{
  stringAppend(results, "a111111111111");
  stringAppend(results, "b2222222222222");
}

void getTimeStamp(char* timeStamp, int timeStampSize)
{
  struct tm *ptr;
  time_t lt;
  lt = time(NULL);
  ptr = localtime(&lt);
  int r = strftime(timeStamp, timeStampSize, "%Y-%m-%d %H:%M:%S", ptr);
}

void stringAppend(char* str1, char* str2)
{   
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1;
  printf("--%i--",arrayLength);

  str1 = realloc(str1, arrayLength);
  if (str1 != NULL)
  {
    strcat(str1, SEPERATOR);
    strcat(str1, str2);
  }
  else
  {
    printf("UNABLE TO ALLOCATE MEMORY\n");
  }
}
4

5 回答 5

7

您正在重新分配str1但没有将值传递出函数,因此可能更改的指针被泄漏,并且已被释放的旧值realloc被您再次释放。这会导致“双重释放”警告。

于 2010-07-07T03:33:21.097 回答
4

问题是当 stringAppend 重新分配指针时,只有 stringAppend 知道这个事实。您需要修改 stringAppend 以获取指向指针 (char **) 的指针,以便更新原始指针。

于 2010-07-07T03:34:23.063 回答
4

stringAppend 中的这一行:

str1 = realloc(str1, arrayLength);

更改 stringAppend 中局部变量的值。这个名为 str1 的局部变量现在指向重新分配的内存或 NULL。

同时 getEvent 中的局部变量保留了它们之前的值,现在通常指向释放的内存。

于 2010-07-07T03:34:50.867 回答
1

所有的评论都非常有帮助。当然,为什么会发生错误是完全有道理的。我最终通过进行以下更改来解决它。

对于 getEvent 和 stringAppend 我都返回 char 指针。

例如

char* stringAppend(char* str1, char* str2) 
{    
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
  printf("--%i--",arrayLength); 

  str1 = realloc(str1, arrayLength); 
  if (str1 != NULL) 
  { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
  } 
  else 
  { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
  } 
  return str1;
} 
于 2010-07-07T04:23:31.133 回答
0

这不是您问题的答案(您不需要,因为错误已被指出),但我对您的代码还有其他一些评论:

char* events= realloc(NULL, 1); 
events[0] = '\0';

您没有测试realloc成功分配的内存。

char* timestamp= realloc(NULL, 20);
timestamp[0] = '\0';

这里同样的问题。在这种情况下,您根本不需要realloc。由于这是一个固定大小的缓冲区,您可以只使用:

char timestamp[20] = "";

不要这样做:

str1 = realloc(str1, arrayLength);

因为如果realloc失败,您将孤立str1之前指向的内存。反而:

char* temp = realloc(str1, arrayLength);
if (temp != NULL)
{
    str1 = temp;
    ...
}

请注意,由于您正在修改stringAppend以返回新字符串,因此您应该在调用函数中进行类似的检查。

此外,“分隔符”拼写为两个 As,而不是两个 E。

于 2010-07-07T06:01:23.240 回答