2012-07-14 90 views
1

我目前正在嘗試學習C++的C端。釋放對象的問題

我試圖malloc256字符數組的一個內存塊,然後我分配它char* "Hello World!",但是當我來釋放該對象時,我得到一個錯誤。

任何人都可以請向我解釋錯誤。

#include <exception> 
#include <stdexcept> 
#include <iostream> 

int main() 
{ 
    void* charVoidPointer = malloc(sizeof(char) * 256) ; 
    charVoidPointer = "Hello World"; 

    std::cout << (char *)charVoidPointer; 
    free (charVoidPointer); 
} 
+3

有一個簡單的規則:**只釋放你從malloc獲得的**。在你的例子中,「Hello World」不是從malloc中獲得的。 – cnicutar 2012-07-14 16:16:35

+0

您正試圖釋放靜態內存,字符串「Hello World」。分配內存後,將指針移動到其他位置,導致內存泄漏。 – 2012-07-14 16:17:01

+1

現在我們知道爲什麼'std :: string'工作得更好! :-) C庫充滿了你永遠不會在C++中使用的東西('strpbrk',任何人?)。除非*必須*,否則不要打擾那些人。 – 2012-07-14 16:24:01

回答

2

「Hello World」由編譯器靜態分配。它是該計劃的一部分,存在於某個可通過該計劃尋址的地方;把它解決12

charVoidPointer最初指向由malloc的分配給你一些的地方;把它解決98

charVoidPointer =「你好......」導致charVoidPointer指向程序中的數據;地址12.你失去了先前包含在charVoidPointer中的地址98的蹤跡。

,你不能釋放內存不會被分配的malloc。

爲了證明字面我的意思:

void* charVoidPointer = malloc(sizeof(char) * 256); 
printf("the address of the memory allocated for us: %p\n", charVoidPointer); 
charVoidPointer = "Hello World"; 
printf("no longer the address allocated for us; free will fail: %p\n", 
     charVoidPointer); 

你的意思是:

strcpy(charVoidPointer, "Hello World"); 

編輯:尋址存儲器,用於其他類型的

的例子
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    // an array of 10 int 
    int *p = (int*)malloc(sizeof(int) * 10); 

    // setting element 0 using memcpy (works for everything) 
    int src = 2; 
    memcpy(p+0, &src, sizeof(int)); 

    // setting element 1 using array subscripts. correctly adjusts for 
    // size of element BECAUSE p is an int*. We would have to consider 
    // the size of the underlying data if it were a void*. 
    p[1] = 3; 

    // again, the +1 math works because we've given the compiler 
    // information about the underlying type. void* wouldn't have 
    // the correct information and the p+1 wouldn't yield the result 
    // you expect. 
    printf("%d, %d\n", p[0], *(p+1)); 

    free (p); 
} 

實驗;將類型從int更改爲long或double,或者一些複雜類型。

+0

Prefect解釋,但你已經演示瞭如何爲malloc創建的對象分配一個void * char *,但是其他任何對象(如float,double或者其他類)都是如此。 – Caesar 2012-07-14 16:26:00

1

使用strcpy(charVoidPointer, "Hello World");因爲在你的例子中你重新指定了你的指針。

1

您將指針指向字符串文字「Hello World」的地址,因此您malloc的內存塊已被泄漏。

您應該使用

strcpy(charVoidPointer, "Hello World"); 

,而不是賦值運算符。

更好的是使用strncpy(charVoidPointer, "Hello World", 255);來避免溢出你分配的數組。

2
void* charVoidPointer = malloc(sizeof(char) * 256) ; 

現在charVoidPointer(怪異名稱的方式 - 如果你想字符,使用char *,並從投malloc返回的指針)在256個字符塊點。此塊未初始化,所以幾乎所有你能做的唯一有效的是他們都設置爲某個值,或複製的東西。

charVoidPointer = "Hello World"; 

現在charVoidPointer代替在靜態分配的字符數組,你我失去了malloc返回的地址。沒有辦法讓它恢復,所以這是資源泄漏。


你的代碼應該是這個樣子:

char *charPointer = (char *)malloc(256); 
strcpy(charPointer, "Hello World"); 

副本字符數組到您分配的塊。或者,更簡潔,只是

char *charPointer = strdup("Hello World"); 

將分配塊大小剛好複製的字符串。你仍然free釋放塊。