我正在尝试实现函数“ int * cpy_array(int v [],int size)”,该函数将数组复制到另一个数组中并返回新数组作为指针。我还必须提防错误情况并使用动态内存。
好吧,我知道当没有足够的可用内存时,malloc返回0。我想知道是否还有其他可能遗漏的错误。然后,无论成功还是错误,我都必须实现free()。 我试图实现类似的东西:
if (!w[i]) {
for (k = 0; k < i; ++k)
free(w[k]);
return 0;
}
但是总是有一个错误。 “在hot.c:2包含的文件中: C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/stdlib.h:502:27:注意:预期为'void *',但参数为输入“ int”” void __cdecl free(void * _Memory);而且我不确定为什么要free()新数组还是应该释放旧数组?我试图在函数中使用指针释放它,但是两者都不起作用,也不认为它应该在主体中?
这是原始代码:
int *cpy_array(int v[], int size);
int main(void)
{
int size;
size = 4;
int myArray[4] = {1234};
if (*cpy_array(myArray, size) == 0)
{
printf("No memory available.");
}else{
printf("The new Array: %i", *cpy_array(myArray, size));
}
return 0;
}
int *cpy_array(int v[], int size)
{
int i;
int *a = malloc(size * sizeof(int));
if(*a == 0)
return 0;
for (i = 0; i < size; i++)
{
a[i] = v[i];
}
return a;
}
答案 0 :(得分:1)
在您的第一个代码段中,您错误地重新分配了整数数组w。您不能在该数组中释放单个整数,但是您只需输入:
free(w);
这将释放整个阵列。 您还可以从错误文本中看到-注意:预期为'void *',但参数的类型为'int'“ void __cdecl free(void * _Memory),该程序预期指向数组的指针而不是整数。
您不能释放旧数组,因为它是静态创建的,并且它的内存是在程序开始时分配的,并且它将在程序本身定义的函数的末尾释放,因此您不必为此担心。释放动态创建的数组(例如通过cpy_array(int v[], int size)
函数创建的数组)是您的工作。
有关静态分配和动态分配之间的区别的更多信息,您可以在此处查找:
Difference between static memory allocation and dynamic memory allocation
这部分代码不会正确地打印数组(您将只打印数组的第一个数字),并且您将调用函数两次,这是多余的,对于同一数组只能执行一次
if (*cpy_array(myArray, size) == 0)
{
printf("No memory available.");
}else{
printf("The new Array: %i", *cpy_array(myArray, size));
}
您可以通过定义一个可以存储该函数返回值的指针来简化这些问题,因此不必调用两次,然后使用for循环正确打印该数组即可。
int * copiedArray = cpy_array(myArray, size);
if (copiedArray == NULL)
{
printf("No memory available.");
}else{
printf("The new Array: ");
for (int i = 0; i < size; i++)
printf("%i ", copiedArray[i]);
}
我注意到您正在检查指针是否指向某物。进入主程序:
if (*cpy_array(myArray, size) == 0)
然后进入cpy_array(int v[], int size)
函数:
if(*a == 0)
这将不起作用,因为您正在取消引用指针并检查其指向的值是否为零。您要做的是检查指针本身的值。如果为NULL,则分配无效:
if (cpy_array(myArray, size) == NULL)
和
if(a == NULL)
您应该使用NULL而不是零,因为您明确声明要检查指针的值,并且NULL可能不等于每台机器上的零。
有关此主题的更多信息:
答案 1 :(得分:0)
要检测与内存有关的问题,请使用 valgrind ,如果我这样做,则会给出:
<Expander KeyboardNavigation.TabNavigation="None" IsExpanded="False" VerticalAlignment="Top" IsEnabled="True" ExpandDirection="Right" />
“有条件的跳转或移动取决于未初始化的值” 来自==10947== Memcheck, a memory error detector
==10947== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10947== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10947== Command: ./a.out
==10947==
==10947== Conditional jump or move depends on uninitialised value(s)
==10947== at 0x10548: cpy_array (c.c:25)
==10947== by 0x104B3: main (c.c:11)
==10947==
==10947== Invalid read of size 4
==10947== at 0x104B8: main (c.c:11)
==10947== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10947==
==10947==
==10947== Process terminating with default action of signal 11 (SIGSEGV)
==10947== Access not within mapped region at address 0x0
==10947== at 0x104B8: main (c.c:11)
==10947== If you believe this happened as a result of a stack
==10947== overflow in your program's main thread (unlikely but
==10947== possible), you can try to increase the size of the
==10947== main thread stack using the --main-stacksize= flag.
==10947== The main thread stack size used in this run was 8388608.
==10947==
==10947== HEAP SUMMARY:
==10947== in use at exit: 16 bytes in 1 blocks
==10947== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==10947==
==10947== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10947== at 0x4847568: malloc (vg_replace_malloc.c:299)
==10947== by 0x10533: cpy_array (c.c:24)
==10947== by 0x104B3: main (c.c:11)
==10947==
==10947== LEAK SUMMARY:
==10947== definitely lost: 16 bytes in 1 blocks
==10947== indirectly lost: 0 bytes in 0 blocks
==10947== possibly lost: 0 bytes in 0 blocks
==10947== still reachable: 0 bytes in 0 blocks
==10947== suppressed: 0 bytes in 0 blocks
==10947==
==10947== For counts of detected and suppressed errors, rerun with: -v
==10947== Use --track-origins=yes to see where uninitialised values come from
==10947== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 6 from 3)
中的*a
和“大小为4的无效读取。 ”。是因为if(*a == 0)
将return 0;
更改为if(*a == 0)
以解决先前的两个问题,即条件(先验)为假,_valgrind说:
if(a == 0)
所以是的,您有内存泄漏,因为丢失了==11116== Memcheck, a memory error detector
==11116== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11116== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11116== Command: ./a.out
==11116==
Mein neuer Array enthaelt folgende Zeichen: 1==11116==
==11116== HEAP SUMMARY:
==11116== in use at exit: 32 bytes in 2 blocks
==11116== total heap usage: 3 allocs, 1 frees, 1,056 bytes allocated
==11116==
==11116== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==11116== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11116== by 0x10523: cpy_array (c.c:24)
==11116== by 0x104A3: main (c.c:11)
==11116==
==11116== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==11116== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11116== by 0x10523: cpy_array (c.c:24)
==11116== by 0x104CF: main (c.c:15)
==11116==
==11116== LEAK SUMMARY:
==11116== definitely lost: 32 bytes in 2 blocks
==11116== indirectly lost: 0 bytes in 0 blocks
==11116== possibly lost: 0 bytes in 0 blocks
==11116== still reachable: 0 bytes in 0 blocks
==11116== suppressed: 0 bytes in 0 blocks
==11116==
==11116== For counts of detected and suppressed errors, rerun with: -v
==11116== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 3)
的分配返回的2倍
您需要输入类似以下内容:
cpy_array
进行校正 valgrind 不会发出任何信号:
int * v = cpy_array(myArray, size);
if (*v == 0)
{
printf("Speicher kann nicht freigegeben werden.");
}else{
printf("Mein neuer Array enthaelt folgende Zeichen: %i",
*v);
}
free(v);
我鼓励你
valgrind --leak-check=full ./a.out
==11224== Memcheck, a memory error detector
==11224== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11224== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11224== Command: ./a.out
==11224==
Mein neuer Array enthaelt folgende Zeichen: 1==11224==
==11224== HEAP SUMMARY:
==11224== in use at exit: 0 bytes in 0 blocks
==11224== total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==11224==
==11224== All heap blocks were freed -- no leaks are possible
==11224==
==11224== For counts of detected and suppressed errors, rerun with: -v
==11224== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
答案 2 :(得分:0)
这不是初始化数组的正确方法
int myArray[4] = {1234};
写
int myArray[4] = { 1,2,3,4 };
或者简单地
int myArray[] = { 1,2,3,4 };
编写时调用函数cpy_array ..
if (*cpy_array(myArray, size) == 0)
不正确,为什么?因为如果该函数返回NULL,那么您将取消引用NULL
在函数cpy_array中,您取消引用a
,这是不正确的,而是比较指针
if ( a == NULL)
,并且将标准常量NULL用于空指针而不是0,因为在所有平台上它可能都不是0。