为什么在分配指针后程序崩溃

时间:2019-07-01 22:37:41

标签: c

管理我的链接列表不起作用。在将值“ next”设置为指向列表的上一个“ head”之后,并且在搜索并找到一个元素之后,我的程序崩溃了。我该怎么办?

该程序可以编译并启动,但是崩溃只是从内存中返回一个随机地址。 我试图更改函数以返回新“ head”的指针,而不是将其无效,但是结果是相同的。 通过验证程序在哪里停止,我发现它停止执行“新节点->下一个=(* head)”,并且在先前的尝试中使用指令“最后返回”。 我试图几乎完全改变函数的功能只是为了理解问题,但是即使我将指针传递给主体并且已经分配了列表,该地址也无法正常工作,并且会崩溃。 只是为了了解发生了什么,假设程序肯定会在条件为“ type_temp =='A'”的情况下进入

这是主要内容:

#include"devices.h"
#include"stdio.h"
#include"string.h"
#include"stdlib.h"


#define LINE_LENGTH 80
#define COMMAND_LENGTH 30


int main(int argc, char** argvs)
{
    FILE *fp;

    struct Type_A** devices_A = NULL;
    struct Type_B** devices_B = NULL;
    struct Type_C** devices_C = NULL;

    struct Request_Type_C** requests_devices_C = NULL;

    int system_power, usable_power, 
        solar_system_power,solar_system_power_temp;

    int id_temp,power_level_temp;
    int power_level_normal_temp, power_level_low_temp;
    char type_temp;

    char file_line[LINE_LENGTH], command[COMMAND_LENGTH];
    char *sub_line;

    fp = fopen("input1.txt","r");

    if(fp == NULL)
    {
        printf("Error opening the file\n");
        return 1;
    }

    if(fgets(file_line,sizeof(file_line),fp) == NULL)
    {
        printf("Error reading the first line\n");
        return 1;
    }

    sub_line = strtok(file_line, " ");
    strcpy(command,sub_line);

    sub_line = strtok(NULL, " ");
    system_power = atoi(sub_line);

    usable_power = system_power;

    while(fgets(file_line,sizeof(file_line),fp) != NULL)
    {
        sub_line = strtok(file_line, " ");
        strcpy(command,sub_line);


        if(strcmp(command,"DEVICE_CONNECTED") == 0)
        {
            sub_line = strtok(NULL, " ");
            id_temp = atoi(sub_line);

            sub_line = strtok(NULL, " ");
            type_temp = *sub_line;

            if(type_temp == 'A')
            {
                sub_line = strtok(NULL, " ");
                power_level_normal_temp = atoi(sub_line);

                sub_line = strtok(NULL, " ");
                power_level_low_temp = atoi(sub_line);

                //function with the problem 1
                add_device_a(devices_A,id_temp,type_temp,
                    power_level_normal_temp,power_level_low_temp,0,0);

                //function with the problem 2
                add_device_a_to_system(devices_A,id_temp,&usable_power);
            }
            .
            .
            .

这是有问题的第一个功能:

void add_device_a(struct Type_A** head, int id, char type,
                    int power_level_normal, int power_level_low,
                    int connected, int consume)
    {
        //allocate the new node
        struct Type_A *new_node = (struct Type_A*) malloc(sizeof(struct Type_A));

        //put in the data
        new_node->id = id;
        new_node->type = type;
        new_node->power_level_normal = power_level_normal;
        new_node->power_level_low = power_level_low;
        new_node->connected = connected;
        new_node->consume = consume;

        //setting the next of the new node
        new_node->next = (*head); <-instruction that generates the problem 
                                    crashing the program 

        //move the head to point to the new node
        (*head) = new_node;

        return;
    } //end add_device_a

这是第二个产生问题的函数:

int add_device_a_to_system(struct Type_A** head, int id, int* usable_power)
{
    struct Type_A *node = find_device_a_by_id(head, id);` <-instruction 

                                         that generates the problem
    .
    .
    .

产生问题的真正功能

struct Type_A *find_device_a_by_id(struct Type_A** head, int id)
{
    //used for traverse the list
    struct Type_A *last = *head;

    //check if last is truly the last node
    while(last != NULL)
    {

        //if the id is equal return the pointer to that node
        if(last->id == id) {
                return last; **<-instruction that makes the program crash**
        }
        //else keep going with the next
        last = last->next;
    }

    //didn't find an id equal to the one passed ad parameter
    return NULL;
}//end of *find_device_a_by_id

向列表中添加元素应首先在链接列表上添加元素,然后修改指向该条目的指针。

找到一个元素应该返回一个指向链表上特定条目的指针。

2 个答案:

答案 0 :(得分:0)

您正在定义一个指向结构体的指针:

struct Type_A** devices_A = NULL;

现在,它没有指向有效的struct Type_A*,因为您还没有创建指向它的指针。因此,当您将其传递给函数add_device_a并取消引用该变量时,您将调用未定义的行为,在这种情况下可能是段错误。 实际上,您可能真正想要的是定义struct Type_A* devices_A = NULL;,然后在将其传递给函数时,传递该指针的地址:

add_device_a(&devices_A,id_temp,type_temp,
    power_level_normal_temp,power_level_low_temp,0,0);

答案 1 :(得分:0)

您可能想将devices_A声明为struct Type_A* devices_A = NULL(而不是双指针),然后使用add_device_a()调用add_device_a(&devices_A, ...

您的操作方式令人困惑,并且需要为devices_A分配空间,在这种情况下,当*headdevices_A时取消引用NULL也会使从地址NULL读取程序,这是未定义的行为,可能会导致崩溃。

您还可以查看this question,了解如何正确管理链接列表。