如何解决为什么此分段错误在整个版本中不一致?
| 我编写了一个c程序,对其进行了编译,并且运行良好。经过几次编译-它开始给我一个分割错误。我重命名了该文件夹,重新编译后它又可以工作了。 这是正常现象吗?出现不一致的细分错误?我更改了输出名称,更改了文件夹名称等。它从提供分段错误反弹到不提供段错误。我不知道该怎么办了。 我的意思是,如果这是编码问题,则段错误应该是一致的,对吗?我应该每次都得到它。这是代码: 文件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;
}
文件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\");
}
文件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获取数字,将其放入列表(无重复),然后打印出来。我使用动态数组列表。
解决方法
初始化变量!
int num = 0;
nodePtr head = NULL; /*head of the list*/
添加:不一致的行为可能来自于调试与发行版的编译,通常是在调试模式下,编译器将未初始化的变量设置为怪异的值,例如“ 4”,以使问题立即可见。在释放模式下,如果将内存块清零,则变量的内容将为0,但不能保证。
,如果返回NULL
(内存不足),则应检查check5的返回值。
,c / c ++程序中的间歇性段错误通常是由未初始化的内存(通常是指针变量)引起的。
您已经发布了很多代码,这使得仅阅读代码就很难调试。我建议遍历代码,并在声明变量的任何地方为其赋予初始值(例如零或NULL)。请记住,编译器不会为您初始化它们。
您可能应该首先在main()
中初始化num
和head
的值。例如。
int num = 0;
nodePtr head = NULL; /*head of the list*/
编辑1
另一个错误出现在addToList()
中。如果未执行该函数中的第一个“ 12”块,则稍后调用“ 14”时,局部变量“ 13”的值将不被使用。当您取消引用p
以获取p->arr,if
p时,则通常会出现段错误。
编辑2
在C / C ++中进行编程时,两种有用的技术:
始终在声明变量时初始化变量。如果不这样做,则它们的值是不确定的。请注意,这并不能解决所有问题。如果取消引用未初始化的指针,则通常会出现段错误。如果将它不完整地设置为null,然后取消引用它,则始终会出现段错误。更容易调试,但仍然崩溃。
始终将变量声明为尽可能靠近首次使用它们的位置。这具有减少使用未初始化变量的机会的效果,因为编译器将生成“未声明变量”错误。在函数开始时声明所有变量的做法是对旧式\'K&R \'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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。