- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我在“main.c”中有类似的东西
#include "foo.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct myStruct
{
int dummyMember1;
float dummyMember2;
} myStruct_t;
int main()
{
myStruct_t* a = malloc(sizeof(myStruct_t));
a->dummyMember1 = 10;
a->dummyMember2 = 5.5;
push(a);
myStruct_t* b = pop();
if(b != NULL)
{
b->dummyMember1;
b->dummyMember2;
}
free(b);
return 0;
}
然后我在某个文件“foo.h”中有类似的东西
void push(void* item);
void* pop();
在“foo.c”中我有这样的东西
#include "foo.h"
#include <stdlib.h>
#include <string.h>
#define ARR_SIZE 50
void* arr[ARR_SIZE];
int free_space = ARR_SIZE;
void push(void* item)
{
if(free_space > 0){
arr[ARR_SIZE - free_space] = item;
free_space--;
}
return;
}
void* pop()
{
void* p_ret = NULL;
if(free_space < ARR_SIZE)
{
void* p = arr[ARR_SIZE-(free_space+1)];
p_ret = malloc(sizeof(*p));
memcpy(p_ret, p, sizeof(*p));
free(p);
free_space++;
}
return p_ret;
}
此代码编译并运行时没有段错误,但问题是 valgrind 报告无效读取错误(即使它显示“所有堆 block 已释放 - 不可能发生泄漏”)。
我的问题是,是什么导致 valgrind 报告无效读取错误(全部引用 pop() 函数)?
最佳答案
您在 push()
和 pop()
中的代码有点复杂。获取您的代码并进行最少的必要更改以在我首选的编译器选项下进行编译,然后在 valgrind
下运行它,我收到警告:
==59504== Invalid read of size 4
==59504== at 0x100000EBF: main (main.c:21)
==59504== Address 0x100aa74e4 is 3 bytes after a block of size 1 alloc'd
==59504== at 0x100007E81: malloc (vg_replace_malloc.c:302)
==59504== by 0x100000E50: pop (foo.c:26)
==59504== by 0x100000EA4: main (main.c:18)
问题出在你的 pop()
函数上;您正在尝试分配 sizeof(*p)
字节,其中 p
是 void *
,因此 *p
是a void
,没有大小。 GCC(在我看来毫无帮助)将其视为对 1
字节的请求,而不是给出应该给出的错误。您必须请求 -pedantic
警告才能获取消息:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror -pedantic -c foo.c
foo.c: In function ‘pop’:
foo.c:26:30: error: invalid application of ‘sizeof’ to a void type [-Werror=pointer-arith]
p_ret = malloc(sizeof(*p));
^
In file included from /usr/include/string.h:186:0,
from foo.c:3:
foo.c:27:32: error: invalid application of ‘sizeof’ to a void type [-Werror=pointer-arith]
memcpy(p_ret, p, sizeof(*p));
cc1: all warnings being treated as errors
$
由于您将 void *
值存储在固定数组中,因此不需要在堆栈中进行任何动态内存分配。您可以使用:
#include "foo.h"
enum { ARR_SIZE = 50 };
static void *arr[ARR_SIZE];
static int free_space = ARR_SIZE;
void push(void *item)
{
if (free_space > 0)
{
arr[ARR_SIZE - free_space] = item;
free_space--;
}
}
void *pop(void)
{
void *p_ret = 0;
if (free_space < ARR_SIZE)
{
p_ret = arr[ARR_SIZE - (free_space + 1)];
free_space++;
}
return p_ret;
}
修改后的测试程序:
#include "foo.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct myStruct
{
int dummyMember1;
float dummyMember2;
} myStruct_t;
int main(void)
{
for (int i = 0; i < 3; i++)
{
myStruct_t *a = malloc(sizeof(myStruct_t));
a->dummyMember1 = 10 + i;
a->dummyMember2 = 5.5 * i;
push(a);
myStruct_t *b = pop();
if (b != NULL)
{
printf("Popped: %d and %f\n", b->dummyMember1, b->dummyMember2);
}
free(a);
}
return 0;
}
我得到 valgrind
输出,例如:
==59611== Memcheck, a memory error detector
==59611== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==59611== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==59611== Command: foo
==59611==
--59611-- run: /usr/bin/dsymutil "./foo"
Popped: 10 and 0.000000
Popped: 11 and 5.500000
Popped: 12 and 11.000000
==59611==
==59611== HEAP SUMMARY:
==59611== in use at exit: 26,437 bytes in 189 blocks
==59611== total heap usage: 274 allocs, 85 frees, 32,661 bytes allocated
==59611==
==59611== LEAK SUMMARY:
==59611== definitely lost: 80 bytes in 1 blocks
==59611== indirectly lost: 68 bytes in 2 blocks
==59611== possibly lost: 0 bytes in 0 blocks
==59611== still reachable: 0 bytes in 0 blocks
==59611== suppressed: 26,289 bytes in 186 blocks
==59611== Rerun with --leak-check=full to see details of leaked memory
==59611==
==59611== For counts of detected and suppressed errors, rerun with: -v
==59611== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
看起来很糟糕——失去了内存。但使用 --leak-check=full
运行会产生:
==59641== 148 (80 direct, 68 indirect) bytes in 1 blocks are definitely lost in loss record 43 of 66
==59641== at 0x100007E81: malloc (vg_replace_malloc.c:302)
==59641== by 0x1001E58D6: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x1001E2553: __rv_alloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x1001E2574: __nrv_alloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x10020B3E6: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x1002346C8: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x10020A389: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x100208223: printf (in /usr/lib/system/libsystem_c.dylib)
==59641== by 0x100000EA4: main (main.c:23)
我尝试添加fclose(stdout)
,但这并没有解决问题。这个问题深埋在本地 printf()
函数内部,完全超出了你我的控制范围。我需要添加一个抑制。 Mac OS X 往往有相当多的此类泄漏 — 见证已经就地的抑制(180 多个分配中几乎 27 KiB)。
如果您确实必须在堆栈中使用内存分配,则需要相当仔细地考虑将哪些内容压入堆栈以及从堆栈中弹出哪些内容。您可能需要知道要存储的对象的大小。然后,您将证明堆栈不会因为修改压入堆栈的值而受到影响,因为堆栈复制了该值。虽然您只是堆叠指针,但只有当当前数组太小时堆栈增长时才需要动态内存分配。
关于c - 即使没有内存泄漏,Valgrind 也会出现无效读取错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35979835/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!