2010-07-07 118 views
0

忍受我。我在8年内没有用c语言编码,而且完全困惑为什么我的字符串操作不起作用。我正在编写一个永久循环的程序。在循环中,我初始化了两个char指针,每个指针都被传递给一个将文本添加到char指针(数组)的函数。当函数完成后,我打印字符指针并释放两个字符指针。但是程序后,7次迭代死与以下错误消息realloc和自由原因“双免费或腐败”

* 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"); 
    } 
} 
+0

请重新格式化:) – KevinDTimm 2010-07-07 03:26:47

+0

@Kevin,如你所愿。 – 2010-07-07 03:30:11

+0

你为什么每次分配循环而不是简单地分配和重用内存? – 2010-07-07 03:31:42

回答

4

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

+2

或者,它可能只是返回'str1'的新值(因为它不会尝试重新分配'str2')。 – caf 2010-07-07 04:03:37

7

你正在重新分配str1但不会将值传递出您的函数,因此潜在更改的指针会泄漏,并且由您自由释放旧值,该值已由realloc释放。这会导致“双重免费”警告。

4

这条线在stringAppend:

str1 = realloc(str1, arrayLength); 

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

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

1

所有评论都非常有帮助。当然,为了发现错误,总是很重要的。我最终通过做出以下更改来解决它。

对于getEvent和stringAppend,我都返回字符指针。

例如

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; 
} 
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,而不是两个Es。