将结构的数据复制到链表中的分段错误

时间:2015-11-18 12:23:01

标签: c data-structures struct segmentation-fault valgrind

我正在尝试将结构的数据复制到链表中。在第757

(*vis_data_collection_tail)->next = p;

我遇到了分段错误。我在这里附加了整个函数和一些Valgrind输出

void insert_netjson_entry(struct vis_v1_extended** vis_data_collection_tail, struct vis_v1* data)
{
    struct vis_v1_extended* p;
    p = malloc(sizeof(struct vis_v1_extended));
    if(p == NULL)
    {
        perror("malloc failure\n");
        exit(EXIT_FAILURE);
    }
    p->entries_n = data->entries_n;
    p->iface_n = data->iface_n;
    strncpy(p->ifaces, data->ifaces, sizeof(p->ifaces));
    strncpy(p->mac,data->mac,sizeof(p->mac));

    p->next = NULL;
    (*vis_data_collection_tail)->next = p;
    (*vis_data_collection_tail) = p;
}

Valgrind输出

[user@localhost alfred-custom] valgrind -v --leak-check=full  --show-leak-kinds=all batadv-vis --format=netjson
==3055== Memcheck, a memory error detector
==3055== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3055== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3055== Command: batadv-vis --format=netjson
==3055== 
--3055-- Valgrind options:
--3055--    -v
--3055--    --leak-check=full
--3055--    --show-leak-kinds=all
--3055-- Contents of /proc/version:
--3055--   Linux version 4.1.7-200.fc22.x86_64 (mockbuild@bkernel02.phx2.fedoraproject.org) (gcc version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC) ) #1 SMP Mon Sep 14 20:19:24 UTC 2015
--3055-- Arch and hwcaps: AMD64, LittleEndian, amd64-rdtscp-sse3
--3055-- Page sizes: currently 4096, max supported 4096
--3055-- Valgrind library directory: /usr/lib64/valgrind
--3055-- Reading syms from /usr/local/sbin/batadv-vis
--3055-- Reading syms from /usr/lib64/ld-2.21.so
--3055--   Considering /usr/lib/debug/.build-id/ee/633c103f1997ad3ef59386f51c0cc17bebafaf.debug ..
--3055--   .. build-id is valid
--3055-- Reading syms from /usr/lib64/valgrind/memcheck-amd64-linux
--3055--    object doesn't have a symbol table
--3055--    object doesn't have a dynamic symbol table
--3055-- Scheduler: using generic scheduler lock implementation.
--3055-- Reading suppressions file: /usr/lib64/valgrind/default.supp
==3055== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-3055-by-caterpillar-on-localhost.localdomain
==3055== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-3055-by-caterpillar-on-localhost.localdomain
==3055== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-3055-by-caterpillar-on-localhost.localdomain
==3055== 
==3055== TO CONTROL THIS PROCESS USING vgdb (which you probably
==3055== don't want to do, unless you know exactly what you're doing,
==3055== or are doing some strange experiment):
==3055==   /usr/lib64/valgrind/../../bin/vgdb --pid=3055 ...command...
==3055== 
==3055== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==3055==   /path/to/gdb batadv-vis
==3055== and then give GDB the following command
==3055==   target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=3055
==3055== --pid is optional if only one valgrind process is running
==3055== 
--3055-- REDIR: 0x4019840 (ld-linux-x86-64.so.2:strlen) redirected to 0x380c10d1 (???)
--3055-- Reading syms from /usr/lib64/valgrind/vgpreload_core-amd64-linux.so
--3055--    object doesn't have a symbol table
--3055-- Reading syms from /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
--3055--    object doesn't have a symbol table
==3055== WARNING: new redirection conflicts with existing -- ignoring it
--3055--     old: 0x04019840 (strlen              ) R-> (0000.0) 0x380c10d1 ???
--3055--     new: 0x04019840 (strlen              ) R-> (2007.0) 0x04c2bce0 strlen
--3055-- REDIR: 0x40195a0 (ld-linux-x86-64.so.2:index) redirected to 0x4c2b880 (index)
--3055-- REDIR: 0x40197c0 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2cd90 (strcmp)
--3055-- REDIR: 0x401a500 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c2fd70 (mempcpy)
--3055-- Reading syms from /usr/lib64/librt-2.21.so
--3055--   Considering /usr/lib/debug/.build-id/45/e5e61b48fb063d1ca0438dc8d43c347aab44c2.debug ..
--3055--   .. build-id is valid
--3055-- Reading syms from /usr/lib64/libc-2.21.so
--3055--   Considering /usr/lib/debug/usr/lib64/libc-2.21.so.debug ..
--3055--   .. CRC mismatch (computed cade4483 wanted 72225548)
--3055-- Reading syms from /usr/lib64/libpthread-2.21.so
--3055--   Considering /usr/lib/debug/.build-id/6e/1fb69fc4248ca0819107eed38c9e8db0b645b3.debug ..
--3055--   .. build-id is valid
--3055-- REDIR: 0x50cc360 (libc.so.6:strcasecmp) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50ce650 (libc.so.6:strncasecmp) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50cbaeb (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50c9d90 (libc.so.6:rindex) redirected to 0x4c2b560 (rindex)
--3055-- REDIR: 0x50cbb40 (libc.so.6:memset) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50cbbb0 (libc.so.6:__GI_memset) redirected to 0x4c2ef60 (memset)
--3055-- REDIR: 0x50c8090 (libc.so.6:strlen) redirected to 0x4c2bc20 (strlen)
--3055-- REDIR: 0x50c8500 (libc.so.6:__GI_strncmp) redirected to 0x4c2c3d0 (__GI_strncmp)
--3055-- REDIR: 0x50c84b0 (libc.so.6:strncmp) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50c9d50 (libc.so.6:strncpy) redirected to 0x4a2372e (_vgnU_ifunc_wrapper)
--3055-- REDIR: 0x50dbea0 (libc.so.6:__GI_strncpy) redirected to 0x4c2bfd0 (__GI_strncpy)
{
--3055-- REDIR: 0x50cbd10 (libc.so.6:__GI_mempcpy) redirected to 0x4c2faa0 (__GI_mempcpy)
  "type" : "NetworkGraph",
--3055-- REDIR: 0x50d30e0 (libc.so.6:strchrnul) redirected to 0x4c2f8a0 (strchrnul)
  "version" : "2015.1-23-ga6b7b07-dirty",
  "metric" : "TQ",
  "nodes" : [
    { "id" : "08:00:27:8f:b1:c2",
      "properties" : {
            "clients" : [
        "33:33:ff:ec:0a:dc",
        "33:33:00:00:00:01",
        "01:00:5e:00:00:01",
        "f2:03:8b:ec:0a:dc"
            ]
--3055-- REDIR: 0x50c0400 (libc.so.6:malloc) redirected to 0x4c28bc9 (malloc)
==3055== Invalid write of size 8
==3055==    at 0x40300B: insert_netjson_entry (vis.c:757)
==3055==    by 0x40328D: vis_read_answer (vis.c:889)
==3055==    by 0x403505: vis_get_data (vis.c:959)
==3055==    by 0x403919: main (vis.c:1086)
==3055==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3055== 
==3055== 
==3055== Process terminating with default action of signal 11 (SIGSEGV)
==3055==  Access not within mapped region at address 0x0
==3055==    at 0x40300B: insert_netjson_entry (vis.c:757)
==3055==    by 0x40328D: vis_read_answer (vis.c:889)
==3055==    by 0x403505: vis_get_data (vis.c:959)
==3055==    by 0x403919: main (vis.c:1086)
==3055==  If you believe this happened as a result of a stack
==3055==  overflow in your program's main thread (unlikely but
==3055==  possible), you can try to increase the size of the
==3055==  main thread stack using the --main-stacksize= flag.
==3055==  The main thread stack size used in this run was 8388608.
          }    }--3055-- REDIR: 0x50c0760 (libc.so.6:free) redirected to 0x4c29ce3 (free)
==3055== 
==3055== HEAP SUMMARY:
==3055==     in use at exit: 16 bytes in 1 blocks
==3055==   total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==3055== 
==3055== Searching for pointers to 1 not-freed blocks
==3055== Checked 225,312 bytes
==3055== 
==3055== 16 bytes in 1 blocks are still reachable in loss record 1 of 1
==3055==    at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3055==    by 0x402F9B: insert_netjson_entry (vis.c:745)
==3055==    by 0x40328D: vis_read_answer (vis.c:889)
==3055==    by 0x403505: vis_get_data (vis.c:959)
==3055==    by 0x403919: main (vis.c:1086)
==3055== 
==3055== LEAK SUMMARY:
==3055==    definitely lost: 0 bytes in 0 blocks
==3055==    indirectly lost: 0 bytes in 0 blocks
==3055==      possibly lost: 0 bytes in 0 blocks
==3055==    still reachable: 16 bytes in 1 blocks
==3055==         suppressed: 0 bytes in 0 blocks
==3055== 
==3055== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==3055== 
==3055== 1 errors in context 1 of 1:
==3055== Invalid write of size 8
==3055==    at 0x40300B: insert_netjson_entry (vis.c:757)
==3055==    by 0x40328D: vis_read_answer (vis.c:889)
==3055==    by 0x403505: vis_get_data (vis.c:959)
==3055==    by 0x403919: main (vis.c:1086)
==3055==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3055== 
==3055== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Errore di segmentazione (core dump creato)

1 个答案:

答案 0 :(得分:2)

替换

p->next = NULL;
(*vis_data_collection_tail)->next = p;
(*vis_data_collection_tail) = p;

由:

p->next = *vis_data_collection_tail;
*vis_data_collection_tail = p;

即使*vis_data_collection_tail碰巧为NULL,这也有效; - &gt;下一个指针将获得NULL值。如果它为NULL,则p-&gt;接下来窃取 *vis_data_collection_tail指向的节点,因此p将自身插入< em>链接列表位于*vis_data_collection_tail指向的位置。