30/09/2018, 19:54

lỗi HEAP CORRUPTION DETECTED

như cái tên topic, mình viết code C thì khi chạy nó báo lỗi này và chương trình bị crash, mình debug thì thấy nó nằm trong hàm unload, nhưng không hiểu tại sao lúc đầu hàm chạy bình thường và giải phóng bộ nhớ ở wordArray[0] nhưng khi nhảy qua wordArray[1] thì lập tức báo lỗi khi mình cố gắng giải phóng nó, code của mình ở dưới, cám ơn mọi người.

#include "lib.h"

int count_wordInDiction = 0;
type_Node* wordArray[25];

bool unload(void)
{
	//lap qua tung 26 o phan tu bang bam
	for (int i = 0; i < 25; i++){
		//o moi o giai phong tung bo nho chua tung tu 1 cho den khi het
		while (wordArray[i] != NULL){
			//giai phong bo nho tu trong struct
			free(wordArray[i]->word_);
			//lay dia chi con tro tiep theo
			type_Node* next = wordArray[i]->next;
			//giai phong con tro hien tai
			free(wordArray[i]);
			//gan vao dia chi tiep theo
			wordArray[i] = next;
		}
	}
	return true;
}

void stringcpy(char A[], const char B[]) // copy chuoi B[] vao chuoi A[]
{
	int i = 0;
	do{
		A[i] = B[i];
		i++;
	} while (B[i] != '');
	A[strlen(B)] = '';
}

unsigned int hashTable(const char* word)
{
	return *word - 97;
}

int tolower(char c)
{
	if (c >= 65 && c <= 90)
		return c + 32;
	else
		return c;
}

bool load(const char* dic)
{
	//tao con tro file de doc data
	FILE* file_diction = NULL;
	fopen_s(&file_diction, dic, "r");
	//kiem tra viec doc du lieu
	if (file_diction == NULL)
		return 1;
	//cap phat bo nho cho bo nho dem, luu tru tu, tu co toi da 45 ky tu nen tao vung nho 46*sizeof(char)
	char* buf_string = NULL;
	buf_string = (char*)malloc(sizeof(char)* 46);
	//kiem tra viec cap phat bo nho
	if (buf_string == NULL)
		return 1;
	//tao dau nhay ao khi doc tu, bat dau tu zero
	int index = 0;
	//tao bien char c de doc tung ky tu trong tu
	char c = 0;
	//tao bien co hieu
	bool flag_hash = true, flag_newWord = true;
	// tao bien bam
	int hash = 0;
	//doc tu va lap cho den khi het du lieu data
	while (c != EOF){
		c = fgetc(file_diction);
		if (flag_hash){
			flag_hash = false;
			hash = hashTable(&c);
			if (wordArray[hash] == NULL)
				flag_newWord = true;
			else
				flag_newWord = false;
		}
		if (flag_newWord){
			if (c == '
'){
				buf_string[index] = '';
				wordArray[hash] = (type_Node*)malloc(sizeof(type_Node));
				//cap phat bo nho cho du lieu chuoi trong node
				wordArray[hash]->word_ = (char*)malloc(sizeof(buf_string));
				//lay du lieu tu bo nho dem truyen vao node moi
				stringcpy(wordArray[hash]->word_, buf_string);
				wordArray[hash]->next = NULL;
				//chuan bi cho tu moi
				index = 0;
				count_wordInDiction++;
				flag_hash = true;
				continue;
			}
			else {
				buf_string[index] = c;
				index++;
			}
		}
		if (!flag_newWord){
			if (c == '
') {
				type_Node* newNode = NULL;
				buf_string[index] = '';
				newNode = (type_Node*)malloc(sizeof(type_Node));
				//cap phat bo nho cho du lieu chuoi trong node
				newNode->word_ = (char*)malloc(sizeof(buf_string));
				//lay du lieu tu bo nho dem truyen vao node moi
				stringcpy(newNode->word_, buf_string);
				//ket noi du lieu
				type_Node* nodecur = wordArray[hash];
				while (nodecur->next != NULL){
					nodecur = nodecur->next;
				}
				nodecur->next = newNode;
				newNode->next = NULL;
				//chuan bi cho tu moi
				index = 0;
				count_wordInDiction++;
				flag_hash = true;
			}
			else {
				buf_string[index] = c;
				index++;
			}
		}
	}
	free(buf_string);
	fclose(file_diction);
	return true;
}

bool check(const char* word)
{
	//tao va cap phat bo nho dem buf_char de luu tu word
	char* buf_char = NULL;
	buf_char = (char*)malloc(sizeof(char)* ((strlen(word) + 1)));
	//kiem tra cap phat bo nho dem
	if (buf_char == NULL)
		return 1;
	//nhap cac ky tu tu word vao bo nho dem, dua ve ky tu chu in thuong
	for (int i = 0; i < strlen(word); i++){
		buf_char[i] = tolower(word[i]);
	}
	//tao ky tu ket thuc chuoi
	buf_char[strlen(word)] = '';
	//bat dau tim kiem
	//tao 1 con tro node* de tim kiem, va gan bang voi gia tri bang bam cua tu khoa word
	type_Node* nodeToCheck = wordArray[hashTable(word)];
	//lap cho den khi het bang, tuc con tro tro toi gia tri NULL
	while (nodeToCheck != NULL) {
		//so sanh cac tu, neu tim duoc tra ve true
		if (strcmp(nodeToCheck->word_, buf_char) == 0){
			return true;
		}
		//neu khong tro toi phan tu tiep theo
		nodeToCheck = nodeToCheck->next;
	}
	//neu het vong lap nghia la khong tim thay, giai phong bo nho dem, va tra ve gia tri false
	free(buf_char);
	return false;
}
Gió viết 21:59 ngày 30/09/2018

Có thể không phải bug trong hàm unload mà ở hàm load:

  • mảng wordArray có 26 kí tự > 25
  • hashTable(&c) không phải lúc náo cũng từ 0-25. *word='A'; hash=-32
  • newNode->word=malloc(sizeof(buf_size)) ;//<=> malloc(sizeof(char*)); <46*sizeof(char)
kiencon viết 22:02 ngày 30/09/2018

thank Gió đã reply,

  • mảng wordArray của mình đúng là có 26 phần tử tương ứng từ a -> z.

  • vì file mình load các ký tự chỉ là chữ in thường a -> z tương ứng từ 0 -> 25, nên hàm hashtable mình thấy không có vấn đề gì.

  • ở phần buf_size mình cấp phát bộ nhớ cho nó chứa 46 ký tự char như code sau:
    buf_string = (char*)malloc(sizeof(char)* 46);
    chương trình sẽ thực hiện việc đọc 1 từ (có tối đa 45 ký tự, đó cũng là lý do mình xin 46 ô char)
    nhưng không phải từ nào cũng có 45 ký tự, có từ chỉ có 1 ký tự nên mình không muốn tốn quá nhiều bộ nhớ cho việc sao lưu qua dữ liệu trong danh sách liên kết, có bấy nhiêu xin bấy nhiêu nên mới dùng:
    wordArray[hash]->word_ = (char*)malloc(sizeof(buf_string));
    liệu có lỗi ở phần này không? cám ơn bạn nhiều
    PS: mình vẫn nghĩ nó có vấn đề ở hàm unload vì sau khi chạy qua hàm load, kiểm tra việc sao dử liệu thấy ok, không có vấn đề gì hết,
    đây là hàm main chạy thử của mình:

    #include “lib.h”

    int main()
    {
    char* word = “age”;
    char* dictionnary = “taptin\small.txt”;
    if (load(dictionnary)){
    bool flag = check(word);
    if (flag)
    printf(“ok!\n”);
    else
    printf(“not ok!\n”);
    }
    unload();
    system(“pause”);
    return 0;
    }

Bài liên quan
0