2015-05-14 75 views
0
void test(){ 
    char *c = malloc(strlen("I like coffe") + 1); 
    strcpy(c, "I like coffe"); 
    char **s = &c; 
    while(strlen(*s) < 25) 
     my_function(s); 
} 

void my_function(char **s){ 
    char *w = *s; 

    char *tmp = realloc(w, len + 2);//Error HERE. *s gets = "" 
    if(tmp != NULL) 
    w = tmp; 
    for(i= len; i>=p; i--){ 
     w[i+1] = w[i]; 
    } 
    w[p] = c;  
} 

该函数用于在char *中插入一个新字符。
另外,这个函数在while循环中。它工作正常,但在第三次循环运行时,它只设置*s = ""
我以为通过使用char *tmp我可以保存数据,如果发生任何错误的事情。我不明白为什么P *s被设置为空字符串。将Realloc设置指针变为空

+1

Betcha你在摆弄“指针指针”时遇到了麻烦。拿起一张纸和一支二号铅笔,离线(!)......“我说,'一张纸和一个二号铅笔!'”......这段代码是什么实际上是在告诉计算机去做。 “你的方式的错误”应该变得明显。 (并且,不,我*不*在这里试图暴露。) –

+0

你永远不会用新地址重新分配父母的背影。不保证realloc(addr)返回地址。实际上,对于大多数自定义分配器,它通常不会。尝试在代码中执行'* s = tmp'而不是'w = tmp'。另外,如果realloc失败(返回NULL),则需要将* s设置为NULL。 – digger

+1

@digger:No;如果realloc()返回NULL,则原始分配不变。 –

回答

3

您忘记了在包含realloc()的函数中将新值分配给*s

void test(void) // Unaltered; still broken! 
{ 
    char *c = malloc(strlen("I like coffe") + 1); 
    strcpy(c, "I like coffe"); 
    char **s = &c; 
    while (strlen(*s) < 25) 
     my_function(s); 
} 

void my_function(char **s) // Fixed one way 
{ 
    char *w = *s; 
    size_t len = strlen(w) + 1; // Define and initialize len 

    char *tmp = realloc(w, len + 2); 
    if (tmp != NULL) 
     w = tmp; 
    *s = w; // Reassign to `*s` 
} 

或者更简单地说:

void my_function(char **s) // Fixed another way 
{ 
    char *w = *s; 
    size_t len = strlen(w); // Define and initialize len 

    char *tmp = realloc(w, len + 2); 
    if (tmp != NULL) 
     *s = tmp; // Reassign to `*s` 
} 

分配到w只设置局部变量这是*s复印件;它不会重置调用代码中的指针。

请注意,即使使用此修复,test()中的循环将运行很长时间,因为没有任何更改c中字符串的长度。还有另一个问题:您没有将s的地址传递给my_function(),因此my_function()无法修改s

void test(void) 
{ 
    char *c = malloc(strlen("I like coffe") + 1); 
    strcpy(c, "I like coffe"); 
    while (strlen(c) < 25) 
    { 
     my_function(&c); 
     strcat(c, "AZ"); // Grow string — not good in real code 
     printf("%2zu: <<%s>>\n", strlen(c), c); 
    } 
} 

void my_function(char **s) 
{ 
    char *w = *s; 
    size_t len = strlen(w) + 1; // Define and initialize len 

    char *tmp = realloc(w, len + 2); 
    if (tmp != NULL) 
     *s = tmp; // Reassign to `*s` 
} 

这会取消指向指向char的指针的指针test()。如果这是至关重要的,那么还有更多想法要做。

代码尚未正式测试过!

现在测试的代码 - 你能说“猪耳朵”吗?复制错误材料的错误使我的测试代码失败。这是仪器化的工作版本 - valgrind为它提供了一个干净的健康法案。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

static void my_function(char **s) 
{ 
    char *w = *s; 
    size_t len = strlen(w) + 1; // Define and initialize len 
    printf("M1: %p: %2zu: <<%s>>\n", (void *)w, len, w); 

    char *tmp = realloc(w, len + 2); 
    if (tmp != NULL) 
     *s = tmp; // Reassign to `*s` 
    printf("M2: %p: %2zu: <<%s>>\n", (void *)*s, strlen(*s), *s); 
} 

static void test(void) 
{ 
    char *c = malloc(strlen("I like coffe") + 1); 
    if (c == 0) 
    { 
     fprintf(stderr, "Out of memory\n"); 
     exit(EXIT_FAILURE); 
    } 
    strcpy(c, "I like coffe"); 
    printf("T1: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c); 
    while (strlen(c) < 25) 
    { 
     my_function(&c); 
     printf("T2: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c); 
     if (c == NULL) 
     { 
      fprintf(stderr, "Out of memory\n"); 
      exit(EXIT_FAILURE); 
     } 
     strcat(c, "AZ"); // Grow string — not good in real code 
     printf("T3: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c); 
    } 
    free(c); 
} 

int main(void) 
{ 
    test(); 
    return 0; 
} 
+0

我以为由于我没有为'w'分配内存,只是将'w'指向与'* s'点相同的本地,它会改变这两者。我不认为这只是一个副本。为什么它只发生在第三次,而不是从我第一次跑步开始。 – PlayHardGoPro

+0

容易混淆,但'w'包含'* s'的副本。修改'w'修改本地副本,而不是原来的。 –

+0

我刚做了另一个测试。这些函数在分离的files.c中。当'my_function()'结束并返回调用者函数时。我可以看到'* s'的修改值。如果它只是一个副本?所以困惑哈哈 – PlayHardGoPro