2013-04-03 64 views
2

對於我的生活,我無法弄清楚爲什麼這個程序不工作。我試圖用三分球來連接兩個字符串,並保持收到此錯誤:在C中使用指針添加字符串

a.out(28095) malloc: *** error 
for object 0x101d36e9c: pointer being realloc'd was not allocated 
*** set a breakpoint in malloc_error_break to debug 

我str_append.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "stringlibrary.h" /* Include the header (not strictly necessary here) */ 

//appends s to d 
void str_append(char *d, char *s){ 
    int i=0, j=0; 

    d = realloc(d, strlength(d)+strlength(s)+1); 
    //find the end of d 
    while(*(d+i)!='\0'){ 
    i++; 
    } 


    //append s to d 
    while(*(s+j)!='\0'){ 
    *(d+i)=*(s+j); 
    i++; 
    j++; 
    } 
    *(d+i)='\0'; 


} 

我有我自己的strlength功能,我100%肯定的作品。

我的main.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "stringlibrary.h" 

int main(int argc, char **argv) 
{ 
char* str = (char*)malloc(1000*sizeof(char)); 
str = "Hello"; 
char* str2 = (char*)malloc(1000*sizeof(char)); 
str2 = " World"; 

str_append(str, str2); 


printf("Original String: %d\n", strlength(str)); 
printf("Appended String: %d\n", strlength(str)); 


return 0; 
} 

我試圖重新分配給一個臨時變量,並收到同樣的錯誤。任何幫助表示讚賞。編輯: 感謝您的所有答案。這個網站真棒。我不僅知道我出錯的地方(我猜想是一個簡單的錯誤),但是我發現了一個我根本不知道的字符串的大漏洞。因爲我不能使用我自己實現的strcpy函數。它基本上是strcpy的源代碼。

char *string_copy(char *dest, const char *src) 
{ 
char *result = dest; 
while (*dest++ = *src++); 
return result; 
} 

回答

5

你的問題是在這裏

char* str = (char*)malloc(1000*sizeof(char)); 
str = "Hello"; 

首先你1000個字符分配空間,你的指針指向內存的開始。
然後在第二行中,將指針指向導致內存泄漏的字符串文字。
您的指針不再指向分配的內存。
然後在您的函數中嘗試更改只讀的字符串文字。

+0

的字符串指針的malloc-ING內存後,分配它,你可能想要做的事的一些數據像strcpy(str,「Hello」); – TheCodeArtist

+0

@ TheCodeArtist和Armin謝謝!哇,我的C技能沒有達到鼻菸,我猜。我怎麼可以去分配一個字符串分配的內存而不使用strcpy?這是一項任務,我不允許使用string.h庫。 – Raz

+0

我會創建一個指向字符串文字開頭的新指針,然後將新指針循環到str指針的分配內存中嗎? – Raz

4

您試圖重新分配一個指向靜態變量的指針。當您設置

str = "Hello";

你靜態分配變量(即它將在​​編譯時分配)。那麼不是有效的指針,用於其他目的,包括realloc。通過丟棄指向該內存的唯一指針,您也正在浪費上述行中檢索到的所有空間(malloc)。

你需要做的,而不是什麼是使用strcpy分配值:

strcpy(str, "Hello");

,那麼你仍然有一個動態分配的指針,你可以使用realloc

+0

謝謝。我錯誤地認爲我將字符串文字分配給分配的內存。我責怪我的Java編碼的唯一經驗,並與C有限的知識。:) – Raz

2
char* str = (char*)malloc(1000*sizeof(char)); 
str = "Hello"; 

應該是:

char* str = malloc (1000); 
strcpy (str, "Hello"); 

前者分配一些存儲器和存儲器的地址存儲到str指針,則改變str指針指向不同(unmalloced)記憶。

這就是爲什麼你會看到pointer being realloc'd was not allocated

後面的代碼段將str指向malloced內存,並將該字符串複製到該內存中。


而且,順便說一句,你永遠不應該從malloc用C把返回值 - 它可以隱藏某些細微的錯誤,這是不必要的,因爲C是完全有能力的隱含鑄造void*返回到任何其他指針類型。

此外,由於sizeof(char)始終爲1,所以您永遠不需要乘以它。它通常會不必要地混淆代碼。

最後,雖然可能不是在這種情況下太重要了,有strmemwcs(每個後跟一個小寫字母)對未來圖書館方向的開始,所以你可能要重新考慮你的東西使用C標準儲備標識符像strlength()如果你想要未來的便攜性。

+0

謝謝。有很多我需要學習,你真的幫助擴展我還沒有弄清楚的一些事情。我是否會使用指向字符串文字開頭的循環將其複製到mallocated內存中? – Raz

+0

@ user2066723,我只會自己使用'strcpy',但如果你不能使用這些函數(例如,作業分配),你可能會像在'str_append'中一樣循環一個字符。 – paxdiablo

1

字符串文字(例如:"MAMA" "MEME")是不可變的。你不能重新分配它們,但是,如果你使用字符指針(例如char * s = (char*)malloc(sizeof(char) * LEN)並分配它們,那麼它們是可變的。

這裏:

char* str = (char*)malloc(1000*sizeof(char)); 
str = "Hello"; //no error BUT wasted memory and cant be reallocated anymore (literal) 

你應該使用內置的函數的字符串操作...