c - 尝试重新排序链表时 free() 无效

标签 c pointers struct malloc valgrind

我试图通过交换指针来重新排序链表。它一直有效,直到我尝试释放内存然后它给我一个错误。

通过交换数据而不是指针,我已经让它工作了,但我很好奇为什么这会导致我的内存出现问题。这是我的代码

typedef struct myArray {
    void *data;
    struct myArray *next;
} myArray_t;

int main(int argc, char **argv) {
    myArray *ma = paramsToList(argc, argv);
    revArray(&ma);
    printArray(ma);
    free(ma);
    return 0;
}

myArray_t *paramsToList(int ac, char *const *av) {
    myArray *ma = (myArray*)malloc((ac) * sizeof(myArray));
    int i = 0;
    while (i < ac) {
        ma[i].data = av[i];
        if (i < ac - 1) {
            ma[i].next = &ma[i + 1];
        } else {
            ma[i].next = NULL;
        }
        i++;
    }
    return ma;
}

void revArray(myArray_t **begin) {
    myArray *cur = begin[0];
    myArray *prev = NULL;
    myArray *next = cur->next;
    while (cur != NULL) {
        cur->next = prev;
        prev = cur;
        cur = next;
        if (cur != NULL) {
            next = cur->next;
        }
    }
    begin[0] = prev;
}

当我运行代码时出现这个错误

valgrind ./a.out one two three

three
two
one
./a.out
==3662== Invalid free() / delete / delete[] / realloc()
==3662==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3662==    by 0x400604: main (example.c:20)
==3662==  Address 0x51fc070 is 48 bytes inside a block of size 64 alloc'd
==3662==    at 0x4C2AB80: malloc (in /usr/lib/valgrind    /vgpreload_memcheck-amd64-linux.so)
==3662==    by 0x40062B: paramsToList(int, char* const*) (example.c:26)
==3662==    by 0x4005DC: main (example.c:17)
==3662== 
==3662== 
==3662== HEAP SUMMARY:
==3662==     in use at exit: 64 bytes in 1 blocks
==3662==   total heap usage: 1 allocs, 1 frees, 64 bytes allocated
==3662== 
==3662== LEAK SUMMARY:
==3662==    definitely lost: 64 bytes in 1 blocks
==3662==    indirectly lost: 0 bytes in 0 blocks
==3662==      possibly lost: 0 bytes in 0 blocks
==3662==    still reachable: 0 bytes in 0 blocks
==3662==         suppressed: 0 bytes in 0 blocks
==3662== Rerun with --leak-check=full to see details of leaked memory
==3662== 
==3662== For counts of detected and suppressed errors, rerun with: -v
==3662== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

最佳答案

您只能向 free() 传递一个由 malloc()/realloc()/calloc() 返回的指针,并且您传递的节点是指向 ma 的指针加上一些偏移量,恰好是 &ma[ac - 1]

您可以只更改节点的内容而不是节点本身,或者只编写一个普通的链表,其中每个节点都使用 malloc() 分配。

关于c - 尝试重新排序链表时 free() 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57778737/

相关文章:

c++ - 为什么 for/while/do-while 在执行相同任务时被放置在 c/c++ 中

c - 位置独立代码、共享库和代码贴面——让它们协同工作

c - void function(stuct *s) 与 void function(stuct s) 有什么区别?

c++ - 奇怪的 vector 初始化问题

将小数转换为指数和尾数

c - 为什么在请求用户再次输入后字符数组为空?

c - C 中的数组语法和指针

c - 需要了解一个用输出覆盖输入的简单示例

c - 如何访问结构中包含的数组的地址?

c# - C++ CLI 结构到字节数组