我写了一个c程序,编译它并运行正常。经过几次编译后 - 它开始给我一个分段错误。我重新命名了文件夹,重新编译,然后再次工作。
这是正常的吗?有一个不一致的分段错误?我改变输出名称,更改文件夹名称等。它从给出分段错误反弹到不给出seg错误。我不知道该怎么办。
我的意思是,如果是编码问题,seg错误应该是一致的,对吧?我每次都应该得到它。这是代码:
文件my_set.c:
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/*
The program acceps a set of numbers from stdin until EOF
And then prints them (not storing duplicate numbers)
*/
int main ()
{
int num;
nodePtr head; /*head of the list*/
while (scanf("%d", &num) != EOF)
{
addToList(num, &head);
}
printList(head);
freeList(head);
return 0;
}
file list.c:
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/*
Implements a linked list, each element of which contains a dynamic array.
I used a linked list to maximize potential memory in case it is fragmented.
I use a dynamic array in each node to minimize the percentage of overhead
from creating a list (the pointer, the index...);
*/
/*
Adds number n to list *h
4 cases:
1. list is empty:
creating one
updating h with new list
creating a new dynamic array in the list
updating it and the index
2. can reallocate current node's array for 1 more int
3. cannot reallocate current node's array:
creating a new node
initializing it
4. cannot create a new node
printing the current list, an "out of memory error" and freeing all memory.
*/
void addToList(int n, nodePtr *h)
{
static nodePtr p; /*points to current last node*/
int *temp; /*for use in reallocation*/
if (!*h) /*first item of set*/
{
*h = malloc (sizeof(node));
(*h)->arr = malloc(sizeof(int));
(*h)->arr[0] = n;
(*h)->i = 1;
p = *h;
return;
}
/*if n is already in the list, no need to add it
the call comes after first item, because first item cannot be in the list*/
if(existsInList(n, *h)) return;
/*using realloc while still possible*/
if ((temp = realloc(p->arr, (p->i+1)*sizeof(int))))
{
p->arr = temp;
p->arr[p->i] = n;
p->i++;
return;
}
/*if realloc no longet possible - start new node*/
if ((p->next = malloc(sizeof(node))))
{
p = p->next;
p->arr = malloc(sizeof(int));
p->arr[0] = n;
p->i = 1;
return;
}
/*can no longer start new nodes - quit with error, after printing*/
printf("out of memory!");
printList(*h);
freeList(*h);
}
/*checks if n is in p assuming p is not null
it can asume so because the call for it comes after the check for first item*/
int existsInList(int n, nodePtr p)
{
int i;
for (; p ; p = p->next)
for (i = 0; i < p->i; i++)
if (p->arr[i] == n)
return 1;
return 0;
}
/*frees the list*/
void freeList(nodePtr p)
{
nodePtr temp = p;
if (!p) return; /*list is empty*/
while (p)
{
free(p->arr);
p = p->next;
free(temp);
}
}
/*prints the content of the list to stdout*/
void printList(nodePtr p)
{
if (!p) return;
int i;
printf("\n");
for (; p ; p = p->next)
for (i = 0; i < p->i; i++)
printf("%d ", p->arr[i]);
printf("\n");
}
file list.h:
/*
pointer to a node
declare a variable of this type to create a list
then start adding to the list
*/
typedef struct s *nodePtr;
/*the struct that represents each node of the list
reason for dynamic array is in "list.c"
*/
typedef struct s
{
int *arr;
int i; /*index for next num, also size of array;*/
nodePtr next;
}node;
/*Adds the int to list at nodePtr omitting duplicates*/
void addToList(int, nodePtr*);
/*prints a list*/
void printList(nodePtr);
/*returns 1 if an int exists in list referenced by nodePtr, 0 otherwise*/
int existsInList(int, nodePtr);
/*frees all dynamically allocated memory*/
void freeList(nodePtr);
基本上我所做的就是从stdin中获取数字,将它们放在一个列表中(没有重复项)然后打印它们。我使用动态数组列表。
答案 0 :(得分:6)
初始化变量!
int num = 0;
nodePtr head = NULL; /*head of the list*/
ADD:不一致的行为可能来自调试与发布编译,通常编译器在调试模式下将非初始化变量设置为奇怪的值,如0xDDDDDDDD
,以使问题立即可见。在释放模式下,如果内存块为零,则会发生变量内容为0但不能保证它。
答案 1 :(得分:1)
c / c ++程序中的间歇段错误通常是由未初始化的内存引起的,通常是在指针变量中。
你发布了很多代码,这使得调试很难阅读。我建议通过代码,无论在哪里声明变量,给它一个初始值(例如零或NULL)。请记住,编译器不会为您初始化它们。
您应该首先在num
中初始化head
和main()
的值。 E.g。
int num = 0;
nodePtr head = NULL; /*head of the list*/
编辑1
addToList()
中的另一个错误。如果未执行该函数中的第一个if
块,则稍后调用p
时将无法初始化局部变量realloc(p->arr, ...)
的值。当您取消引用p
以使p->arr, if
p'未初始化时,您通常会获得段错误。
编辑2
使用C / C ++编程时的两种有用技巧:
所以,而不是:
int foo() // Warning: bad code
{
int a;
int b;
func1();
a=func2(&b);
return a;
}
尝试类似:
int foo()
{
func1();
int b = 42;
int a = func2(&b);
return a;
}
答案 2 :(得分:1)
如果它返回malloc()
(内存不足),您应该检查NULL
的返回值。