Zwalnianie pamięci przez free() w C

0

Witam, mam problem ze zwalnianiem pamięci w funkcji createitem. Gdzie bym nie umieścił free() to program się sypie. Już nie wiem o co tu chodzi. Dziwne jest też to, że w Visualu po wpisaniu danych pojawia się błąd, a w Devie wszystko działa tylko zamiast właściwych danych wyświetlają się krzaki. Komunikat błędu wygląda tak:"CRT detected that applicaton wrote to memory after end of heap buffer.", a przecież to nie prawda(przynajmniej tak mi się wydaje). Dodam jeszcze, że bez zwalniania pamięci wszystko działa jak trzeba. Będę wdzięczny za pomoc.

Oto fragment mojego programu:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
typedef struct LIST List;
typedef struct DATA Data;

struct DATA
{
	char* word;
	char* replacer;
};
struct LIST
{
	Data data;
	List* next;
};
List* head;

int showlist()
{
	List *temp;

	system("cls");
	temp = head;
	if (temp == NULL)
	{
		printf("Brak elementow\n");
		getch();
		return 1;
	}
	else
		printf("WYRAZY:     ZAMIENNIKI:\n");
	while (temp != NULL)
		{
			printf("%-12s%-12s\n", temp->data.word, temp->data.replacer);
			temp = temp->next;
		}
	getch();
	return 0;
}

List* createitem()
{
	List *element;
	char *word, *replacer;
	char  bufor[30];
	
	system("cls");
	printf("Podaj wyraz oraz zamiennik, ktore chcesz dodac do listy\n\n");
	printf("Wyraz: ");
	gets(bufor);
	word = (char*)malloc((strlen(bufor)+1) * sizeof(char));
	strcpy(word, bufor);
	printf("Zamiennik: ");
	gets(bufor);
	replacer = (char*)malloc((strlen(bufor)+1)*sizeof(char));
	strcpy(replacer, bufor);
	element = (List*)malloc(sizeof(List));
	element->next = NULL;
	element->data.word = word;
	element->data.replacer = replacer;

	free(word);
    free(replacer);

	return element;
}

void additem()
{
	List *tmp = createitem();
	
	if (head != NULL)
		tmp->next = head;
	head = tmp;
}
	
int main(int argc, char **argv)
{
	additem();
	showlist();

	return 0;
}
3

Pozwolilem sobie skrocic Twoj kod do linii istotnych na potrzeby mojej wypowiedzi. A wiec mamy cos takiego:

List* createitem()
{
	word = (char*)malloc((strlen(bufor)+1) * sizeof(char));
	replacer = (char*)malloc((strlen(bufor)+1)*sizeof(char));

	element->data.word = word;
	element->data.replacer = replacer;

	free(word);
	free(replacer);
}

Najpierw alokujesz sobie pamiec, ktorej adres przechowujesz w zmiennych word i replacer. Pozniej za pomoca linii:

	element->data.word = word;
	element->data.replacer = replacer;

Kopiujesz adresy przechowywane w zmiennych word i replacer do element->data.word i element->data.replacer. Podkreslam: adresy a nie istotne dla Ciebie dane. Nastepnie zwalniasz pamiec pod adresami, w ktorych te dane sa. Efekt jest taki, ze robiac delete na zmiennych word i replacer usuwasz dane zarowno z word i replacer jak i z element->data.word i element->data.replacer. Dane te oczywiscie musisz usunac ale nie na tym etapie - raczej na etapie zwalniania calej listy lub usuwania poszczegolnych elementow z listy. Lepiej by bylo napisac te funkcje mniej-wiecej tak:

List* createitem()
{
	element = (List*)malloc(sizeof(List));
	element->next = NULL;

	gets(bufor);
	element->data.word = (char*)malloc((strlen(bufor)+1) * sizeof(char));
	strcpy(element->data.word, bufor);

	gets(bufor);
	element->data.replacer =  (char*)malloc((strlen(bufor)+1)*sizeof(char));	
	strcpy(element->data.replacer, bufor);

	return element;
}

Powinno dzialac (nie sprawdzalem).

0

Jest fajna funkcja strdup()

1 użytkowników online, w tym zalogowanych: 0, gości: 1