2011-07-04 25 views
5

Tôi có một đoạn mã nhỏ. Tôi biên soạn nó với -lmcheck vì tôi đang cố gắng gỡ lỗi mã mà tôi có cùng lỗi tương tự.Lỗi Clobbering bộ nhớ

tôi nhận được lỗi này khi tôi chạy mã này:

memory clobbered before allocated block 

Ai đó có thể giải thích lý do tại sao free(ptr) sẽ ném tôi lỗi này?

Làm cách nào khác để tôi có thể giải phóng con trỏ?

Cảm ơn.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#define LEN 5 


int main(int argc, char *argv[]){ 

    char *ptr = NULL; 

    ptr = (char *) malloc(LEN+1);// +1 for string 
    strcpy(ptr, "hello"); 

    int i = 0; 
    for(i = 0; i<LEN; i++) 
    { 
     printf("ptr[%d] = %c\n", i, ptr[i]); 
     ptr++; 
    } 
    free(ptr); 


    return 0; 
} 
+0

Ngoài ra, hãy xem xét http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858. – unwind

Trả lời

8

Bạn đang gia tăng ptr, do đó thay đổi địa chỉ trỏ đến. Bạn không thể làm điều đó.

Trong trường hợp của bạn, có một con trỏ riêng biệt, giả sử char * p = ptr và làm hoạt động của bạn với p rời ptr nguyên vẹn, do đó bạn có thể free(ptr) sau.

EDIT Xem lại mã của bạn lần hai, tôi thấy rằng bạn đang thực hiện ptr++ khi bạn không nên. Bạn đang truy cập các ký tự trong mảng như ptr[i], nếu bạn lộn xộn với con trỏ ptr, bạn đang thay đổi địa chỉ cơ sở và truy cập các ký tự với ptr[i] có thể dẫn (và sẽ dẫn) đến kết quả không mong muốn.

Nếu bạn chỉ cần xóa dòng đó (ptr++) mã của bạn sẽ hoạt động một cách kỳ diệu. Nếu bạn muốn khám phá những khái niệm con trỏ và thử một giải pháp khác, mã của bạn có thể trông giống như thế này:

int main(int argc, char *argv[]){ 

    char *ptr = NULL; 
    char * p; 

    ptr = (char *) malloc(LEN+1);// +1 for string (please check for NULL) 
    p = ptr; 

    strcpy(ptr, "hello"); 

    int i = 0; 
    while (*p) // note how I changed it to a while loop, C strings are NULL terminated, so this will break once we get to the end of the string. What we gain is that this will work for ANY string size. 
    { 
     printf("ptr[%d] = %c\n", i++, *p); // here i dereference the pointer, accessing its individual char 
     p++; 
    } 
    free(ptr); 


    return 0; 
} 
+1

Giải thích tuyệt vời! Cảm ơn bạn đã đi thêm dặm. –

2

ptr điểm không còn để các cơ sở của bộ nhớ mà bạn được giao.

1

Ngoài ra, sau khi bạn tăng ptr, biểu thức ptr[i] không trả về những gì bạn có thể mong đợi; và đó là lý do tại sao đầu ra bắt đầu bằng "hlo".

1

Tìm câu trả lời trong nhận xét. Khi bạn cấp phát một số bộ nhớ, thông thường, khung quản lý bộ nhớ sẽ theo dõi nó bằng cách thêm một số thông tin khác (bạn có thể nói Đầu trang và Chân trang) vào vùng bộ nhớ được cấp phát. Khi bạn giải phóng bộ nhớ này, thông tin tương tự sẽ được so khớp để phát hiện bất kỳ truy cập bộ nhớ không mong muốn/không hợp lệ nào.

int main(int argc, char *argv[]){ 

    char *ptr = NULL; 
    char* temp = NULL;   // Have a temp pointer. 

    ptr = (char *) malloc(LEN+1);// +1 for string 
    strcpy(ptr, "hello"); 

    temp = ptr;     // manipulate temp pointer instead of ptr itself 

    int i = 0; 
    for(i = 0; i<LEN; i++) 
    { 
     printf("ptr[%d] = %c\n", i, temp[i]); 
     temp++;     // Why you are incrementing this? Just to print, there is no need of this. 
    } 
    free(ptr); 


    return 0; 
} 
Các vấn đề liên quan