【问题标题】:Member access within misaligned address with linked-list使用链表在未对齐地址中的成员访问
【发布时间】:2017-12-29 04:24:06
【问题描述】:

所以我正在计算problem number 2 of leetcode(基本上你在一个列表中得到了两个数字,需要对它们求和并在一个倒置的列表中返回答案)。但是,我不断收到这个烦人的错误:“运行时错误:类型'struct ListNode'的未对齐地址0x000000000031内的成员访问,需要8字节对齐”。我在我的机器上运行它,它工作正常,给出了预期的结果。我的代码:

/*Definition of the list:
struct ListNode {
         int val;
         struct ListNode* next;
    };*/

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode* answer = malloc(sizeof(struct ListNode));
    answer->next = NULL;
    answer->val = 0;
    int auxInt = 0;
    struct ListNode* auxVar = answer;

    while(l1 != NULL || l2 != NULL) {
        if(!l1) {
            auxInt = answer->val;
            answer->val = (auxInt + l2->val) % 10;
            if(((l2->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l2->val + auxInt) /10;
            }
            l2 = l2->next;
        }
        else if(!l2) {
            auxInt = answer->val;
            answer->val = (auxInt + l1->val) % 10;
            if(((l1->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l1->val + auxInt) /10;
            }
            l1 = l1->next;
        } else {
            auxInt = answer->val;
            answer->val = (l1->val + l2->val + auxInt) % 10;
            if(((l1->val + l2->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l1->val + l2->val + auxInt) /10;
            }
            l1 = l1->next;
            l2 = l2->next;
        }
        if(l1 == NULL && l2 == NULL)
            break;
        else
        {
            if(!answer->next)
                answer->next = malloc(sizeof(struct ListNode));
            answer = answer->next;
            answer->next = NULL;
        }
    }
    return auxVar;
}

对可能导致此问题的原因有什么想法吗?感谢您的宝贵时间。

编辑:这是一个可验证的示例,其中包含导致崩溃的数字:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int val;
    struct ListNode *next;
};

/*typedef struct InvertedList {
    int val;
    struct InvertedList *next;
    struct InvertedList *previous;
}Lista;*/

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode* answer = malloc(sizeof(struct ListNode));
    answer->next = NULL;
    answer->val = 0;
    int auxInt = 0;
    struct ListNode* auxVar = answer;

    while(l1 != NULL || l2 != NULL) {
        if(!l1) {
            auxInt = answer->val;
            answer->val = (auxInt + l2->val) % 10;
            if(((l2->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l2->val + auxInt) /10;
            }
            l2 = l2->next;
        }
        else if(!l2) {
            auxInt = answer->val;
            answer->val = (auxInt + l1->val) % 10;
            if(((l1->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l1->val + auxInt) /10;
            }
            l1 = l1->next;
        } else {
            auxInt = answer->val;
            answer->val = (l1->val + l2->val + auxInt) % 10;
            if(((l1->val + l2->val + auxInt) / 10) != 0) {
                answer->next = malloc(sizeof(struct ListNode));
                answer->next->val = (l1->val + l2->val + auxInt) /10;
            }
            l1 = l1->next;
            l2 = l2->next;
        }
        if(l1 == NULL && l2 == NULL)
            break;
        else
        {
            if(!answer->next)
                answer->next = malloc(sizeof(struct ListNode));
            answer = answer->next;
        }
    }
    return auxVar;
}

void adicionaLista(struct ListNode* ptrLista, char *array, int size) {
    struct ListNode *auxNode = ptrLista;
    for(int i = 0; i < size; i++) {
        ptrLista->val = array[i];
        if(i + 1 != size) {
            ptrLista->next = malloc(sizeof(struct ListNode));
            ptrLista = ptrLista->next;
        }
    }
    ptrLista = auxNode;
    printf("\n");
}
void printAnswer(struct ListNode *ptrAnswer) {
    for(; ptrAnswer != NULL; ptrAnswer = ptrAnswer->next)
        printf("%d ", ptrAnswer->val);
}

int main()
{
    struct ListNode *l1 = malloc(sizeof(struct ListNode));
    struct ListNode *l2 = malloc(sizeof(struct ListNode));
    char lista[9] = {4,5,2,2,9,3,8,9,2};
    char lista2[9] = {0,7,6,1,6,5,0,6,7};
    adicionaLista(l1, lista, 9);
    adicionaLista(l2, lista2, 9);
    struct ListNode *answer = addTwoNumbers(l1, l2);
    printAnswer(answer);
    return 0;
} 

【问题讨论】:

  • 您尚未提供 MCVE (minimal reproducible example)。您没有提供合适的样本数据。您还没有展示列表是如何构建的。您还没有向我们提供打印方法。你需要提供一个 MCVE 和样本数据——这些类型的数据会导致你的代码崩溃。 (如果你知道崩溃的数据,在别人的机器上崩溃可能没问题。)你用Valgrind分析出了什么问题吗?
  • 使用调试器。仔细看看answer-&gt;next = malloc(...)之后会发生什么
  • @JonathanLeffler 抱歉,这对我来说不是很周到。我已根据您的要求编辑了问题。
  • 我建议使用函数来创建新节点。肯定有一些地方你没有完全初始化节点,特别是下一个指针,这就是导致你的代码对我来说崩溃的原因。
  • adicionaLista 最后一个 next 未初始化 NULL。始终存在同样的问题。

标签: c linked-list


【解决方案1】:

主要问题是最后一个元素中的next 未设置为NULL
次要问题是……

  1. 预计不会创建空列表,即创建无用节点的情况。
  2. 代码中有很多重复。这使得更改代码变得困难。
  3. printf("\n"); 不应包含在数据的附加功能中。它应该在输出函数中使用。

固定和精简的代码

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int val;
    struct ListNode *next;
};

struct ListNode *addTwoNumbers(struct ListNode *l1, struct ListNode *l2) {
    struct ListNode anchor  = { .next = NULL }, *curr = &anchor;
    int carry = 0;
    while(l1 != NULL || l2 != NULL || carry) {
        int val1 = 0, val2 = 0;
        if(l1) {
            val1 = l1->val;
            l1 = l1->next;
        }
        if(l2) {
            val2 = l2->val;
            l2 = l2->next;
        }
        int answer = val1 + val2 + carry;
        carry = answer > 9;//val1 and val2 are one digit.
        curr = curr->next = malloc(sizeof(struct ListNode));
        curr->val = answer % 10;
        curr->next = NULL;
    }
    return anchor.next;
}

struct ListNode *makeListFromChars(const char *array, int size) {
    struct ListNode anchor  = { .next = NULL }, *curr = &anchor;

    for(int i = 0; i < size; i++) {
        curr = curr->next = malloc(sizeof(struct ListNode));//Creating lists and adding data is a separate function.
        curr->val = array[i];
        curr->next = NULL;
    }
    return anchor.next;
}

void printList(struct ListNode *p) {
    for(; p; p = p->next)
        printf("%d ", p->val);
    printf("\n");
}

int main(void){
    char lista1[9] = {4,5,2,2,9,3,8,9,2};
    char lista2[9] = {0,7,6,1,6,5,0,6,7};
    struct ListNode *l1 = makeListFromChars(lista1, 9);
    struct ListNode *l2 = makeListFromChars(lista2, 9);

    printList(l1);
    printList(l2);

    struct ListNode *answer = addTwoNumbers(l1, l2);
    printList(answer);
    //freeList(l1);freeList(l2);freeList(answer);
    return 0;
} 

【讨论】:

  • 我遇到了同样的问题,但在您的帮助下找到了问题并被接受。 Here 是我的工作代码。
  • 如果您立即将NULL 分配给curr-&gt;next,为什么还要curr = curr-&gt;next = ...
猜你喜欢
  • 2022-11-11
  • 2020-11-08
  • 2019-04-28
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
相关资源
最近更新 更多