如何为结构字段正确分配内存?

问题描述 投票:0回答:2

问题很不言自明。我想实现一个函数,该函数创建具有初始容量为[.C0]的动态数组和内部某些属性的结构。这是代码:

initial_capacity

这是#include <malloc.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> typedef struct IntVector { int *vector; unsigned int capacity; unsigned int size; } IntVector; IntVector *int_vector_new(size_t initial_capacity) { struct IntVector v = {calloc(initial_capacity, sizeof(int)), initial_capacity, 0}; IntVector* v_ptr = &v; return v_ptr; } 所说的:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes -v ./debug

如您所见,我已经连续三个小时试图解决此问题,但没有任何进展。希望对您有所帮助。

c memory-management struct malloc calloc
2个回答
2
投票

功能

==1713== Memcheck, a memory error detector
==1713== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1713== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1713== Command: ./debug
==1713==
--1713-- Valgrind options:
--1713--    --leak-check=full
--1713--    --show-leak-kinds=all
--1713--    --track-origins=yes
--1713--    -v
--1713-- Contents of /proc/version:
--1713--   Linux version 4.4.0-18362-Microsoft ([email protected]) (gcc version 5.4.0 (GCC) ) #476-Microsoft Fri Nov 01 16:53:00 PST 2019
--1713--
--1713-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-avx2-bmi
--1713-- Page sizes: currently 4096, max supported 4096
--1713-- Valgrind library directory: /usr/lib/valgrind
--1713-- Reading syms from /home/altbrace/IntVector/debug
--1713-- Reading syms from /lib/x86_64-linux-gnu/ld-2.27.so
--1713--   Considering /lib/x86_64-linux-gnu/ld-2.27.so ..
--1713--   .. CRC mismatch (computed 1b7c895e wanted 2943108a)
--1713--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.27.so ..
--1713--   .. CRC is valid
--1713-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--1713--   Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--1713--   .. CRC mismatch (computed 41ddb025 wanted 9972f546)
--1713--    object doesn't have a symbol table
--1713--    object doesn't have a dynamic symbol table
--1713-- Scheduler: using generic scheduler lock implementation.
--1713-- Reading suppressions file: /usr/lib/valgrind/default.supp
==1713== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-1713-by-altbrace-on-???
==1713== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-1713-by-altbrace-on-???
==1713== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-1713-by-altbrace-on-???
==1713==
==1713== TO CONTROL THIS PROCESS USING vgdb (which you probably
==1713== don't want to do, unless you know exactly what you're doing,
==1713== or are doing some strange experiment):
==1713==   /usr/lib/valgrind/../../bin/vgdb --pid=1713 ...command...
==1713==
==1713== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==1713==   /path/to/gdb ./debug
==1713== and then give GDB the following command
==1713==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=1713
==1713== --pid is optional if only one valgrind process is running
==1713==
==1713== error calling PR_SET_PTRACER, vgdb might block
--1713-- REDIR: 0x401f2f0 (ld-linux-x86-64.so.2:strlen) redirected to 0x580608c1 (???)
--1713-- REDIR: 0x401f0d0 (ld-linux-x86-64.so.2:index) redirected to 0x580608db (???)
--1713-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--1713--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--1713--   .. CRC mismatch (computed 50df1b30 wanted 4800a4cf)
--1713--    object doesn't have a symbol table
--1713-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--1713--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--1713--   .. CRC mismatch (computed f893b962 wanted 95ee359e)
--1713--    object doesn't have a symbol table
==1713== WARNING: new redirection conflicts with existing -- ignoring it
--1713--     old: 0x0401f2f0 (strlen              ) R-> (0000.0) 0x580608c1 ???
--1713--     new: 0x0401f2f0 (strlen              ) R-> (2007.0) 0x04c32db0 strlen
--1713-- REDIR: 0x401d360 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c33ee0 (strcmp)
--1713-- REDIR: 0x401f830 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c374f0 (mempcpy)
--1713-- Reading syms from /lib/x86_64-linux-gnu/libc-2.27.so
--1713--   Considering /lib/x86_64-linux-gnu/libc-2.27.so ..
--1713--   .. CRC mismatch (computed b1c74187 wanted 042cc048)
--1713--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.27.so ..
--1713--   .. CRC is valid
--1713-- REDIR: 0x4edac70 (libc.so.6:memmove) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9d40 (libc.so.6:strncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edaf50 (libc.so.6:strcasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9790 (libc.so.6:strcat) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9d70 (libc.so.6:rindex) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edc7c0 (libc.so.6:rawmemchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edade0 (libc.so.6:mempcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edac10 (libc.so.6:bcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9d00 (libc.so.6:strncmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9800 (libc.so.6:strcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edad40 (libc.so.6:memset) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ef80f0 (libc.so.6:wcschr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9ca0 (libc.so.6:strnlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9870 (libc.so.6:strcspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edafa0 (libc.so.6:strncasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9840 (libc.so.6:strcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edb0e0 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9da0 (libc.so.6:strpbrk) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed97c0 (libc.so.6:index) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ed9c70 (libc.so.6:strlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ee46c0 (libc.so.6:memrchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edaff0 (libc.so.6:strcasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edabe0 (libc.so.6:memchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4ef8eb0 (libc.so.6:wcslen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4eda050 (libc.so.6:strspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edaf20 (libc.so.6:stpncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edaef0 (libc.so.6:stpcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edc7f0 (libc.so.6:strchrnul) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4edb040 (libc.so.6:strncasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--1713-- REDIR: 0x4fca3c0 (libc.so.6:__strrchr_avx2) redirected to 0x4c32730 (rindex)
--1713-- REDIR: 0x4ed6030 (libc.so.6:calloc) redirected to 0x4c31a70 (calloc)
--1713-- REDIR: 0x4ed3950 (libc.so.6:free) redirected to 0x4c30cd0 (free)
==1713==
==1713== HEAP SUMMARY:
==1713==     in use at exit: 20 bytes in 1 blocks
==1713==   total heap usage: 1 allocs, 0 frees, 20 bytes allocated
==1713==
==1713== Searching for pointers to 1 not-freed blocks
==1713== Checked 69,336 bytes
==1713==
==1713== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1713==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1713==    by 0x1086F2: int_vector_new (IntVector.c:13)
==1713==    by 0x1086BB: main (main.c:8)
==1713==
==1713== LEAK SUMMARY:
==1713==    definitely lost: 20 bytes in 1 blocks
==1713==    indirectly lost: 0 bytes in 0 blocks
==1713==      possibly lost: 0 bytes in 0 blocks
==1713==    still reachable: 0 bytes in 0 blocks
==1713==         suppressed: 0 bytes in 0 blocks
==1713==
==1713== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1713== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

返回一个指向声明的局部变量的指针,如

IntVector *int_vector_new(size_t initial_capacity) {
        struct IntVector v = {calloc(initial_capacity, sizeof(int)),
                               initial_capacity, 0};
        IntVector* v_ptr = &v;
        return v_ptr;
}

因此,退出函数后,指针具有无效值,因为指向的对象不再存在。

要么动态分配结构类型的对象,然后将指针返回给分配的内存。或按值将对象v本身返回给函数的调用者。

例如

struct IntVector v

IntVector int_vector_new(size_t initial_capacity) {
        struct IntVector v = {calloc(initial_capacity, sizeof(int)),
                               initial_capacity, 0};
        return v;
}

您可以添加检查是否成功分配了内存。


0
投票

我不知道可能会发生什么事情,因为目前您还没有任何代码可以显示调用的位置,但是我看到了一个大问题。您将返回指向在IntVector * int_vector_new(size_t initial_capacity) { struct IntVector* v_ptr = malloc( sizeof( struct Inventor ) ); v_ptr->vector = calloc( initial_capacity, sizeof(int)); v_ptr->capacity = initial_capacity; v_ptr->size = 0; return v_ptr; } 中创建的值的指针,因此一旦该函数返回指向(int_vector_new)的局部变量,就将消失。

您可以为v分配内存,就像这样:v

然后使用IntVector* v = malloc(sizeof(IntVector));语法设置每个字段。像这样:

->

由于valgrind抱怨泄漏,所以我猜您稍后不会在代码中释放IntVector* v = malloc(sizeof(IntVector)); v->vector = calloc(initial_capacity, sizeof(int)); v->capacity = initial_capacity; v->size = 0; return v; 。释放内存将解决有关内存泄漏的投诉。使用capacity分配malloc后,您将需要释放v返回的所有值。

© www.soinside.com 2019 - 2024. All rights reserved.