释放分配的内存会产生分段错误
freeing allocated memory generates segmentation fault
我尝试从文本文件中读取,然后将每个单词放入列表节点(然后以相反的顺序打印)。
程序运行良好,但是当试图释放分配的列表节点时,程序崩溃。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
typedef struct node{
char* word;
struct node* next;
}; typedef struct node* list;
void freeall(list lst){
list temp = NULL;
while (lst)
{
temp = lst->next;
free(lst);
lst = temp;
}
#if 0
if (lst == NULL){ return; }
freeall(lst->next);
free(lst->word);
free(lst);
#endif // 0
}
void deleteAllNodes(list start)
{
while (start != NULL)
{
list temp = start;
free(temp);
start = start->next;
}
}
list createNode(char* buff){
list newnode = (list)malloc(sizeof(list));
assert(newnode);
newnode->next = NULL;
newnode->word = (char*)calloc(strlen(buff), sizeof(char));
assert(newnode->word);
strcpy(newnode->word, buff);
return newnode;
}
void reverse(const char *str) //you don't need to modify your string
{
if (*str != '[=10=]'){ //if the first character is not '\O'
reverse((str + 1)); // call again the function but with +1 in the pointer addr
printf("%c", *str); // then print the character
}
}
void print_reverse(list lst){
if (lst == NULL) return;
print_reverse(lst->next);
reverse(lst->word);
//free(lst->word);
}
list createList(FILE* ifp){
struct node *loop = NULL;
list curr = NULL;
list lst = NULL;
char *word = NULL;
size_t size = 2;
long fpos = 0;
char format[32];
if (ifp == NULL) // open file
perror("Failed to open file \n");
if ((word = malloc(size)) == NULL) // word memory
perror("Failed to allocate memory");
sprintf(format, "%%%us", (unsigned)size - 1); // format for fscanf
while (fscanf(ifp, format, word) == 1) {
while (strlen(word) >= size - 1) { // is buffer full?
size *= 2; // double buff size
printf("** doubling to %u **\n", (unsigned)size);
if ((word = realloc(word, size)) == NULL)
perror("Failed to reallocate memory");
sprintf(format, "%%%us", (unsigned)size - 1);// new format spec
fseek(ifp, fpos, SEEK_SET); // re-read the line
if (fscanf(ifp, format, word) == 0)
perror("Failed to re-read file");
}
curr = createNode(word);
if (lst == NULL){lst = curr;}
else{
loop = lst;
while (loop->next != NULL) {//loop to last structure
loop = loop->next;//add structure to end
}
loop->next = curr;
}
fpos = ftell(ifp); // mark file pos
}
free(word);
return lst;
}
int main(int argc, char* argv[]){
assert(argc == 2);
FILE *ifp = fopen(argv[1], "r");
assert(ifp);
list lst = NULL;
lst = (list)malloc(sizeof(list));
lst = createList(ifp);
print_reverse(lst);
fclose(ifp);
//freeall(lst);
//deleteAllNodes(lst);
return 1;
}
在您的 deleteAllNodes
函数中,您正在释放一个指针然后访问它。您可以尝试以相反的顺序删除节点,从最后一个开始,例如使用递归函数。
void deleteAllNodes(list start)
{
if (start != NULL)
{
deleteAllNodes(start->next);
free(start);
}
}
或者您可以坚持使用类似(未测试)的迭代向前删除:
void deleteAllNodes(list start)
{
list previous = NULL;
while (start != NULL)
{
if (previous != NULL)
free(previous);
previous = start;
start = start->next;
}
if (previous != NULL)
free(previous);
}
您的 delete all nodes
有一个错误。您释放了一个指针并尝试立即访问它。所以程序崩溃了 你可以试试这个
void deleteAllNodes(list head)
{
list ptr = head;
while ((ptr = head) != NULL)
{
head = head->next;
free (ptr);
}
}
将当前ptr指向head并将head指向下一个元素。删除当前指针。
据我所知,问题出在
list newnode = (list)malloc(sizeof(list));
你的 list
是 struct node*
的类型定义,所以这个语句本质上是
list newnode = (list)malloc(sizeof(struct node*));
这是错误的。您正在为指向结构变量的指针分配内存,而您分配的内存应该等于结构变量本身的大小。
这里有两件事要提
- 请see why not to cast
malloc()
和C
中家人的return值。
- 切勿将
typedef
用于指针类型。这不是"rule",但最好坚持下去。
您的分配声明,至少,应类似于
list = malloc(sizeof*list);
除此之外,在您的 main()
函数中,
- 首先,您使用
malloc()
将内存分配给 lst
[与上述分配问题相同]
- 然后,你分配另一个指针,
createList()
的return值给lst
。
这样,您将通过 malloc()
覆盖分配的内存,创建 memory leak。你根本不需要malloc()
。
我尝试从文本文件中读取,然后将每个单词放入列表节点(然后以相反的顺序打印)。
程序运行良好,但是当试图释放分配的列表节点时,程序崩溃。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
typedef struct node{
char* word;
struct node* next;
}; typedef struct node* list;
void freeall(list lst){
list temp = NULL;
while (lst)
{
temp = lst->next;
free(lst);
lst = temp;
}
#if 0
if (lst == NULL){ return; }
freeall(lst->next);
free(lst->word);
free(lst);
#endif // 0
}
void deleteAllNodes(list start)
{
while (start != NULL)
{
list temp = start;
free(temp);
start = start->next;
}
}
list createNode(char* buff){
list newnode = (list)malloc(sizeof(list));
assert(newnode);
newnode->next = NULL;
newnode->word = (char*)calloc(strlen(buff), sizeof(char));
assert(newnode->word);
strcpy(newnode->word, buff);
return newnode;
}
void reverse(const char *str) //you don't need to modify your string
{
if (*str != '[=10=]'){ //if the first character is not '\O'
reverse((str + 1)); // call again the function but with +1 in the pointer addr
printf("%c", *str); // then print the character
}
}
void print_reverse(list lst){
if (lst == NULL) return;
print_reverse(lst->next);
reverse(lst->word);
//free(lst->word);
}
list createList(FILE* ifp){
struct node *loop = NULL;
list curr = NULL;
list lst = NULL;
char *word = NULL;
size_t size = 2;
long fpos = 0;
char format[32];
if (ifp == NULL) // open file
perror("Failed to open file \n");
if ((word = malloc(size)) == NULL) // word memory
perror("Failed to allocate memory");
sprintf(format, "%%%us", (unsigned)size - 1); // format for fscanf
while (fscanf(ifp, format, word) == 1) {
while (strlen(word) >= size - 1) { // is buffer full?
size *= 2; // double buff size
printf("** doubling to %u **\n", (unsigned)size);
if ((word = realloc(word, size)) == NULL)
perror("Failed to reallocate memory");
sprintf(format, "%%%us", (unsigned)size - 1);// new format spec
fseek(ifp, fpos, SEEK_SET); // re-read the line
if (fscanf(ifp, format, word) == 0)
perror("Failed to re-read file");
}
curr = createNode(word);
if (lst == NULL){lst = curr;}
else{
loop = lst;
while (loop->next != NULL) {//loop to last structure
loop = loop->next;//add structure to end
}
loop->next = curr;
}
fpos = ftell(ifp); // mark file pos
}
free(word);
return lst;
}
int main(int argc, char* argv[]){
assert(argc == 2);
FILE *ifp = fopen(argv[1], "r");
assert(ifp);
list lst = NULL;
lst = (list)malloc(sizeof(list));
lst = createList(ifp);
print_reverse(lst);
fclose(ifp);
//freeall(lst);
//deleteAllNodes(lst);
return 1;
}
在您的 deleteAllNodes
函数中,您正在释放一个指针然后访问它。您可以尝试以相反的顺序删除节点,从最后一个开始,例如使用递归函数。
void deleteAllNodes(list start)
{
if (start != NULL)
{
deleteAllNodes(start->next);
free(start);
}
}
或者您可以坚持使用类似(未测试)的迭代向前删除:
void deleteAllNodes(list start)
{
list previous = NULL;
while (start != NULL)
{
if (previous != NULL)
free(previous);
previous = start;
start = start->next;
}
if (previous != NULL)
free(previous);
}
您的 delete all nodes
有一个错误。您释放了一个指针并尝试立即访问它。所以程序崩溃了 你可以试试这个
void deleteAllNodes(list head)
{
list ptr = head;
while ((ptr = head) != NULL)
{
head = head->next;
free (ptr);
}
}
将当前ptr指向head并将head指向下一个元素。删除当前指针。
据我所知,问题出在
list newnode = (list)malloc(sizeof(list));
你的 list
是 struct node*
的类型定义,所以这个语句本质上是
list newnode = (list)malloc(sizeof(struct node*));
这是错误的。您正在为指向结构变量的指针分配内存,而您分配的内存应该等于结构变量本身的大小。
这里有两件事要提
- 请see why not to cast
malloc()
和C
中家人的return值。 - 切勿将
typedef
用于指针类型。这不是"rule",但最好坚持下去。
您的分配声明,至少,应类似于
list = malloc(sizeof*list);
除此之外,在您的 main()
函数中,
- 首先,您使用
malloc()
将内存分配给lst
[与上述分配问题相同] - 然后,你分配另一个指针,
createList()
的return值给lst
。
这样,您将通过 malloc()
覆盖分配的内存,创建 memory leak。你根本不需要malloc()
。