1. 程式人生 > >釋放記憶體出現HEAP CORRUPTION DETECTED錯誤

釋放記憶體出現HEAP CORRUPTION DETECTED錯誤

今天敲程式碼,出現了HEAP CORRUPTION DETECTED錯誤,本來指標分配記憶體,最後再釋放記憶體空間是天經地義的事情,竟然報錯,開始也摸不著頭腦,最後百度了一下,最終發現問題是,我分配了len長度的空間,我卻用到了len + 1的長度,釋放的時候就報錯了。貼下我的程式碼,主要是實現將兩種記憶體模型裡的資料拷貝到第三種記憶體模型中,並且排序輸出:

#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include"stdlib.h"
#include"string.h"

int getzip(char** p1, int num1, char
(*p2)[30], int num2, char*** p3, int *num) { int ret = 0; char** tmp = NULL; int num3 = 0; if (p1 == NULL || p2 == NULL || p3 == NULL) { ret = 1; printf("func getzip 傳入了空地址: %d\n", ret); return ret; } num3 = num1 + num2; tmp = (char**)malloc(sizeof(char
*) * num3); if (tmp == NULL) { ret = 1; printf("func getzip 記憶體分配失敗: %d\n", ret); return ret; } for (int i = 0; i < num1; i++) { int len = strlen(p1[i]) + 1; tmp[i] = (char*)malloc(len); if (tmp[i] == NULL) { ret = 2; printf("func getzip 記憶體分配失敗: %d\n"
, ret); goto END; } strcpy(tmp[i], p1[i]); //tmp[i][len] = '\0'; //錯誤在這裡 } for (int i = 0; i < num2; i++) { int len = strlen(p2[i]) + 1; tmp[num1 + i] = (char*)malloc(len); if (tmp[i] == NULL) { ret = 2; printf("func getzip 記憶體分配失敗: %d\n", ret); goto END; } strcpy(tmp[num1 + i], p2[i]); //tmp[num1 + i][len] = '\0'; //錯誤在這裡 } END: if (ret != 0) { if (tmp != NULL) { for (int i = 0; i < num3; i++) { if (tmp[i] != NULL) free(tmp[i]); } free(tmp); } } else { *p3 = tmp; *num = num3; } return 0; } int print_str(char** p3, int num3) { int ret = 0; if (p3 == NULL) { ret = 1; printf("func print_str 傳入了空地址: %d\n", ret); return ret; } for (int i = 0; i < num3; i++) { if(p3[i] != NULL) printf("%s\n", p3[i]); } return 0; } int sort_str(char** p3, int num3) { int ret = 0; char* tmp = NULL; if (p3 == NULL) { ret = 1; printf("func print_str 傳入了空地址: %d\n", ret); return ret; } for (int i = 0; i < num3; i++) { for (int j = i + 1; j < num3; j++) { if (strcmp(p3[i], p3[j]) > 0) { tmp = p3[i]; p3[i] = p3[j]; p3[j] = tmp; } } } return 0; } void freemem(char*** p3, int num3) { int ret = 0; char** tmp = NULL; if (p3 == NULL || *p3 == NULL) return; tmp = *p3; for (int i = 0; i < num3; i++) { if (tmp[i] != NULL) free(tmp[i]); } free(tmp); *p3 = NULL; return ; } int main(){ int ret = 0; int num1 = 3, num2 = 4; int num3 = 0; char *p1[] = {"2222222", "333333333", "111111111111"}; char p2[4][30] = {"nnnnnn", "oooooooo", "ddddddddd", "bbbbbbbbb"}; char** p3 = NULL; getzip(p1, num1, p2, num2, &p3, &num3); print_str(p3, num3); sort_str(p3, num3); print_str(p3, num3); freemem(&p3, num3); system("pause"); return 0; }

當初忘記了strcpy是會把’\0’一起拷貝過去的,順便把strcpy實現的原始碼貼在這裡:

char *strcpy(char *strDest, const char *strSrc);
{
assert((strDest!=NULL) && (strSrc !=NULL)); 
char *address = strDest; 
while( (*strDest++ = * strSrc++) != ‘\0’ ) 
NULL ;
return address ; 
}

然後自己加了一句:

tmp[i][len] = '\0'; 

本來記憶體空間只開闢了len長度,我這算是用到len + 1個長度了,類似越界了,所以釋放的時候就會報錯,感覺應該是釋放空間時,查到使用了本來不屬於這個指標所指向的空間,就會釋放出錯。如果改成:

tmp[i][len - 1] = '\0'; 

這樣子釋放也沒有問題,所以感覺釋放出問題,差不多就是分配記憶體空間或者使用記憶體空間時出問題了。