realloc 和 free 会导致“双重释放或损坏”

发布于 2024-09-08 14:18:31 字数 1664 浏览 14 评论 0原文

耐心听我说。我已经 8 年没有用 c 编写代码了,我完全困惑为什么我的字符串操作不起作用。我正在编写一个永远循环的程序。在循环中,我初始化两个 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");
  }
}

Bear with me. I have not coded in c in 8 years and am totally baffled why my string manipulation is not working. I am writing a program that loops forever. In the loop I initialize two char pointers each is passed to a function that add text to the char pointer (array). When the functions are done I print the char pointer and free the two char pointers. However the program dies after 7 iterations with the following error message

* glibc detected * ./test: double free or corruption (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(<);
  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");
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

为你拒绝所有暧昧 2024-09-15 14:18:31

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

You are reallocating str1 but not passing the value out of your function, so the potentially changed pointer is leaked, and the old value, which has been freed by realloc, is freed again by you. This causes the "double free" warning.

凉墨 2024-09-15 14:18:31

问题是,当 stringAppend 重新分配指针时,只有 stringAppend 知道这一事实。您需要修改 stringAppend 以采用指针到指针(char **),以便更新原始指针。

The problem is that while stringAppend reallocates the pointers, only stringAppend is aware of this fact. You need to modify stringAppend to take pointer-to-pointers (char **) so that the original pointers are updated.

π浅易 2024-09-15 14:18:31

stringAppend 中的这一行:

str1 = realloc(str1, arrayLength);

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

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

This line in stringAppend:

str1 = realloc(str1, arrayLength);

changes the value of a local variable in stringAppend. This local variable named str1 now points to either the reallocated memory or NULL.

Meanwhile local variables in getEvent keep the values they had before, which now usually point to freed memory.

子栖 2024-09-15 14:18:31

所有的评论都非常有帮助。当然,错误发生的原因是完全有道理的。我最终通过进行以下更改解决了这个问题。

对于 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;
} 

All the comments where very helpfull. Of course it makes total sense why the error was happening. I ended up solving it by making the following changes.

For both the getEvent and stringAppend I return the char pointer.

e.g.

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;
} 
简单气质女生网名 2024-09-15 14:18:31

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

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 以返回新字符串,因此您应该在调用函数中执行类似的检查。

另外,“separator”由两个 As 拼写,而不是由两个 E 拼写。

This isn't an answer to your question (and you don't need one, since the error has been pointed out), but I do have some other comments about your code:

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

You don't test that realloc successfully allocated memory.

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

Same problem here. In this case, you don't need realloc at all. Since this is a fixed-size buffer, you could use just:

char timestamp[20] = "";

And don't do this:

str1 = realloc(str1, arrayLength);

because if realloc fails, you'll orphan the memory that str1 was pointing to before. Instead:

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

Note that since you're modifying stringAppend to return the new string, you should do similar checks in the calling functions.

Also, "separator" is spelled with two As, not with two Es.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文