2015-05-14 74 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