为什么此分段错误在整个版本中不一致?

问题描述

| 我编写了一个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;
}
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...