复杂数据类型的 Valgrind "Memory Error"
Valgrind "Memory Error" with complex data type
我写了一个 C 程序,它是带有链表的堆栈的通用实现。我尝试反转一些字符串、整数数组、双精度数组,并且效果很好。我使用 valgrind 检查内存泄漏和错误,仍然没有问题。但是,当我尝试反转复杂数据类型(例如结构类型)的数组时,即使没有泄漏并且输出正确,我也会收到内存错误。
所以,
我哪里做错了?
Invalid write of size 8
是什么意思?
还有这个 - Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd
是什么意思?
// 以下是来自 valgrind 的错误日志:
==74356== HEAP SUMMARY:
==74356== in use at exit: 0 bytes in 0 blocks
==74356== total heap usage: 7 allocs, 7 frees, 1,096 bytes allocated
==74356==
==74356== All heap blocks were freed -- no leaks are possible
==74356==
==74356== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
==74356==
==74356== 3 errors in context 1 of 2:
==74356== Invalid read of size 8
==74356== at 0x109425: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== Address 0x4e44618 is 0 bytes after a block of size 8 alloc'd
==74356== at 0x4A36ECB: malloc (vg_replace_malloc.c:307)
==74356== by 0x109587: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356==
==74356==
==74356== 3 errors in context 2 of 2:
==74356== Invalid write of size 8
==74356== at 0x4A3E333: memmove (vg_replace_strmem.c:1270)
==74356== by 0x1095A2: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd
==74356== at 0x4A36ECB: malloc (vg_replace_malloc.c:307)
==74356== by 0x109587: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356==
==74356== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
// 下面是程序 -
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define SIZE 3
typedef struct node{
void * data;
struct node * next;
}NODE;
typedef struct stack{
NODE * top;
}STACK;
typedef struct comp{
double real;
double imaginary;
}COMPLEX;
NODE * newNode (void * data, size_t size);
bool isEmpty (NODE * top);
NODE * push (NODE * top, void * data, size_t size);
NODE * pop (NODE * top);
void reverse (COMPLEX arr[], int n);
int main (void)
{
COMPLEX arr[SIZE] = {
{1.7, 2.3},
{2.4, 3.5},
{3.1, 4.8}
};
printf ("Before reversing-\n");
for (int i = 0; i < SIZE; i++)
printf ("%.1lf + %.1lfi\n", arr[i].real, arr[i].imaginary);
reverse (arr, SIZE);
putchar ('\n');
printf ("After reversing-\n");
for (int i = 0; i < SIZE; i++)
printf ("%.1lf + %.1lfi\n", arr[i].real, arr[i].imaginary);
return 0;
}
void reverse (COMPLEX arr[], int n)
{
STACK S = {.top = NULL};
for (int i = 0; i < n; i++)
S.top = push (S.top, &arr[i], sizeof (COMPLEX));
for (int i = 0; i < n; i++)
{
* ((COMPLEX *) (&arr[i])) = * ((COMPLEX *) (S.top->data));
S.top = pop (S.top);
}
}
NODE * newNode (void * data, size_t size)
{
NODE * new_Node = malloc (sizeof (NODE));
new_Node->data = malloc (sizeof (size));
memcpy (new_Node->data, data, size);
new_Node->next = NULL;
return new_Node;
}
bool isEmpty (NODE * top)
{
if (top == NULL)
return true;
return false;
}
NODE * push (NODE * top, void * data, size_t size)
{
NODE * new_Node = newNode (data, size);
if (isEmpty (top))
top = new_Node;
else
{
new_Node->next = top;
top = new_Node;
}
return top;
}
NODE * pop (NODE * top)
{
if (isEmpty (top))
fprintf (stderr, "Stack is empty. Cannot perform pop operation.\n");
else
{
NODE * next = top->next;
free (top->data);
free (top);
top = next;
}
return top;
}
What I am I doing wrong?
malloc (sizeof (size));
无效。那是 sizeof(size_t)
- size
具有的类型的大小。变量 size
已经保存了某物的 大小 的值。所以只需传递 size
.
new_Node->data = malloc(size);
// ^^ ugh
What does Invalid write of size 8 mean ?
这意味着您的程序试图写入不允许写入的无效内存地址。写入操作试图写入 8 个字节。
Also what does this - Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd mean ?
您为 malloc(sizeof(size))
分配的字节数不足,但 memcpy
正试图在那里写入字节数。地址 0x4e444d8
是 memcpy
试图写入的地址 - 它是“0 字节”/紧跟在 malloc
分配的内存之后,而你用 [=] 分配了 8 个字节20=]打电话。
我写了一个 C 程序,它是带有链表的堆栈的通用实现。我尝试反转一些字符串、整数数组、双精度数组,并且效果很好。我使用 valgrind 检查内存泄漏和错误,仍然没有问题。但是,当我尝试反转复杂数据类型(例如结构类型)的数组时,即使没有泄漏并且输出正确,我也会收到内存错误。
所以,
我哪里做错了?
Invalid write of size 8
是什么意思?还有这个 -
Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd
是什么意思?
// 以下是来自 valgrind 的错误日志:
==74356== HEAP SUMMARY:
==74356== in use at exit: 0 bytes in 0 blocks
==74356== total heap usage: 7 allocs, 7 frees, 1,096 bytes allocated
==74356==
==74356== All heap blocks were freed -- no leaks are possible
==74356==
==74356== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
==74356==
==74356== 3 errors in context 1 of 2:
==74356== Invalid read of size 8
==74356== at 0x109425: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== Address 0x4e44618 is 0 bytes after a block of size 8 alloc'd
==74356== at 0x4A36ECB: malloc (vg_replace_malloc.c:307)
==74356== by 0x109587: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356==
==74356==
==74356== 3 errors in context 2 of 2:
==74356== Invalid write of size 8
==74356== at 0x4A3E333: memmove (vg_replace_strmem.c:1270)
==74356== by 0x1095A2: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd
==74356== at 0x4A36ECB: malloc (vg_replace_malloc.c:307)
==74356== by 0x109587: newNode (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x109490: push (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1093E3: reverse (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356== by 0x1092DA: main (in /home/arnab/MyWorkspace/c-workspace/test/generic_functions/test_node/test)
==74356==
==74356== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
// 下面是程序 -
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define SIZE 3
typedef struct node{
void * data;
struct node * next;
}NODE;
typedef struct stack{
NODE * top;
}STACK;
typedef struct comp{
double real;
double imaginary;
}COMPLEX;
NODE * newNode (void * data, size_t size);
bool isEmpty (NODE * top);
NODE * push (NODE * top, void * data, size_t size);
NODE * pop (NODE * top);
void reverse (COMPLEX arr[], int n);
int main (void)
{
COMPLEX arr[SIZE] = {
{1.7, 2.3},
{2.4, 3.5},
{3.1, 4.8}
};
printf ("Before reversing-\n");
for (int i = 0; i < SIZE; i++)
printf ("%.1lf + %.1lfi\n", arr[i].real, arr[i].imaginary);
reverse (arr, SIZE);
putchar ('\n');
printf ("After reversing-\n");
for (int i = 0; i < SIZE; i++)
printf ("%.1lf + %.1lfi\n", arr[i].real, arr[i].imaginary);
return 0;
}
void reverse (COMPLEX arr[], int n)
{
STACK S = {.top = NULL};
for (int i = 0; i < n; i++)
S.top = push (S.top, &arr[i], sizeof (COMPLEX));
for (int i = 0; i < n; i++)
{
* ((COMPLEX *) (&arr[i])) = * ((COMPLEX *) (S.top->data));
S.top = pop (S.top);
}
}
NODE * newNode (void * data, size_t size)
{
NODE * new_Node = malloc (sizeof (NODE));
new_Node->data = malloc (sizeof (size));
memcpy (new_Node->data, data, size);
new_Node->next = NULL;
return new_Node;
}
bool isEmpty (NODE * top)
{
if (top == NULL)
return true;
return false;
}
NODE * push (NODE * top, void * data, size_t size)
{
NODE * new_Node = newNode (data, size);
if (isEmpty (top))
top = new_Node;
else
{
new_Node->next = top;
top = new_Node;
}
return top;
}
NODE * pop (NODE * top)
{
if (isEmpty (top))
fprintf (stderr, "Stack is empty. Cannot perform pop operation.\n");
else
{
NODE * next = top->next;
free (top->data);
free (top);
top = next;
}
return top;
}
What I am I doing wrong?
malloc (sizeof (size));
无效。那是 sizeof(size_t)
- size
具有的类型的大小。变量 size
已经保存了某物的 大小 的值。所以只需传递 size
.
new_Node->data = malloc(size);
// ^^ ugh
What does Invalid write of size 8 mean ?
这意味着您的程序试图写入不允许写入的无效内存地址。写入操作试图写入 8 个字节。
Also what does this - Address 0x4e444d8 is 0 bytes after a block of size 8 alloc'd mean ?
您为 malloc(sizeof(size))
分配的字节数不足,但 memcpy
正试图在那里写入字节数。地址 0x4e444d8
是 memcpy
试图写入的地址 - 它是“0 字节”/紧跟在 malloc
分配的内存之后,而你用 [=] 分配了 8 个字节20=]打电话。