是说delete pointer和pointer = nullptr一样吗?可能不是,但后者会释放内存吗?怎么样delete pointer; pointer = nullptr/ pointer = nullptr; delete pointer?为什么不使用它来提供一种安全的方法来过早地删除指针,如果需要,通常会在其他时间删除它们并导致正常删除错误?
在下面的代码段中free(x),为什么会y变为0?
根据我的理解,堆中被指向x并且仍然被指向的内存y尚未分配给其他人,那么如何将其更改为0?
此外,我认为不会free(x)将其改为0.
任何意见?
#include <stdio.h>
int main(int argc, char *argv[])
{
int *y = NULL;
int *x = NULL;
x = malloc(4);
*x = 5;
y = x;
printf("[%d]\n", *y); //prints 5
free(x);
printf("[%d]\n", *y); //why doesn't print 5?, prints 0 instead
return 0;
}
Run Code Online (Sandbox Code Playgroud) 经历了一些痛苦的经历后,我理解了悬挂指针和双重自由的问题.我正在寻求适当的解决方案
aStruct 有许多字段,包括其他数组.
aStruct *A = NULL, *B = NULL;
A = (aStruct*) calloc(1, sizeof(sStruct));
B = A;
free_aStruct(A);
...
// Bunch of other code in various places.
...
free_aStruct(B);
Run Code Online (Sandbox Code Playgroud)
有没有办法写出free_aStruct(X)这样才能free_aStruct(B)优雅地退出?
void free_aStruct(aStruct *X) {
if (X ! = NULL) {
if (X->a != NULL) { free(X->a); x->a = NULL; }
free(X); X = NULL;
}
}
Run Code Online (Sandbox Code Playgroud)
上述操作仅A = NULL在free_aStruct(A);调用时设置.B现在正在晃来晃去.
如何避免/纠正这种情况?引用计数是唯一可行的解决方案吗?或者,是否有其他"防御性"方法来释放记忆,防止free_aStruct(B);爆炸?
假设我有两个容器存储指向同一对象的指针:
std::list<Foo*> fooList;
std::vector<Foo*> fooVec;
Run Code Online (Sandbox Code Playgroud)
假设我从其中一个容器中移除一个对象,如果它的方法是:
std::vector<Foo*>::iterator itr =
std::find( fooVec.begin(), fooVec.end(), pToObj );
fooVec.erase( itr );
Run Code Online (Sandbox Code Playgroud)
CppReference说这会调用对象的析构函数.这是否意味着指向对象的指针fooList是悬空指针?
我不想使用引用计数指针.如何处理这个问题?
N3290 C++草案,第12.2节,第5点,第10行.
第二个上下文是引用绑定到临时的.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
在new-initializer(5.3.4)中对引用的临时绑定将持续到包含new-initializer的full-expression完成为止.[例如:
Run Code Online (Sandbox Code Playgroud)struct S { int mi; const std::pair<int,int>& mp; }; S a { 1, {2,3} }; S* p = new S{ 1, {2,3} };// Creates dangling reference- 结束示例] [注意:这可能会引入悬空引用,并鼓励实现在这种情况下发出警告. - 结束说明]
与C++ 03相比,这是一个补充点.但这个例子对我来说是不可理解的.你能用其他任何例子来解释这一点吗?
我知道悬空引用和临时对象是什么,并且std::pair包含两个可能不同数据类型的值.
c++ language-lawyer temporary-objects c++11 dangling-pointer
我们已经知道免费使用后漏洞可能会导致安全问题.由于免费使用后错误是由悬空指针产生的,我的问题是如果悬挂指针没有在程序中使用,它们被认为是安全的还是良性的(不是那么危险)?
我想混合 co_yielding 字符串文字和std::strings
Generator<std::string_view> range(int first, const int last) {
while (first < last) {
char ch = first++;
co_yield " | ";
co_yield std::string{ch, ch, ch};
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道 std::string 的生命周期?
如果您知道要string_view立即食用,也许是安全的?
for(auto sv : range(65, 91))
std::cout << sv;
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/d5eoP9aTE
你可以像这样保证安全
Generator<std::string_view> range(int first, const int last) {
std::string result;
while (first < last) {
char ch = first++;
co_yield " | ";
result = std::string{ch, ch, ch};
co_yield result;
}
}
Run Code Online (Sandbox Code Playgroud) 假设我有以下内容:
struct Foo {
Foo () : bar(NULL), box(true) {}
Bar* bar;
bool box;
};
Run Code Online (Sandbox Code Playgroud)
我宣布以下内容:
std::vector<Foo> vec(3);
Run Code Online (Sandbox Code Playgroud)
我现在有一个功能,它做了这样的事情:
Foo& giveFoo() { //finds a certain foo and does return vec[i]; }
Run Code Online (Sandbox Code Playgroud)
然后调用者将Foo其通过引用获得的地址传递Foo*给其他人.然而,我想知道的是,如果这个指针Foo在触发向量增长后仍然有效vec吗?如果现有的Foo元素vec被复制,那么大概Foo*是浮动的那个现在会悬空?是这种情况吗?我正在调试一个应用程序,但无法重现这个.
我正在用 c 开发一个项目,我试图了解如何调试一个使我的程序崩溃的模糊错误。它有点大,通过制作较小版本的代码来隔离问题的尝试是行不通的。所以我试图想出一种方法来调试和查明内存泄漏。
我想出了以下计划:我知道问题来自运行某个函数,并且该函数递归调用自身。所以我想我可以为我的程序内存分配做一个快照。由于我不知道 jack 引擎盖下会发生什么(我知道在这种情况下还不够有用):
typedef struct record_mem {
int num_allocs;
int num_frees;
int size_space;
int num_structure_1;
...
int num_structure_N;
int num_records;
struct record_mem *next;
} RECORD;
extern RECORD *top;
void pushmem(RECORD **top)
{
RECORD *nnew = 0;
RECORD *nnew = (RECORD *)malloc(sizeof(RECORD));
nnew->num_allocs=1;
nnew->num_frees=0;
nnew->size_space=sizeof(RECORD);
nnew->num_structure_1=0;
...
nnew->num_structure_N=0;
nnew->num_records=1;
nnew->next=0;
if(*top)
{
nnew->num_allocs+=(*top)->num_allocs;
nnew->num_frees=(*top)->num_frees;
nnew->size_space+=(*top)->size_space;
nnew->num_structure_1=(*top)->num_allocs;
...
nnew->num_structure_N=(*top)->num_allocs;
nnew->num_records+=(*top)->num_records;
nnew->next=*top;
}
*top=nnew;
}
Run Code Online (Sandbox Code Playgroud)
我的想法是在我的程序崩溃之前打印出我的内存记录的内容(由于 GDB,我知道它在哪里崩溃)。
然后在整个程序中(对于我程序中的每个数据结构,我都有一个类似上面的推送函数)我可以简单地添加一个带有计算数据结构分配加上总堆栈(堆?)内存分配(我可以跟踪的)。我只是在我觉得需要记录我的程序运行的快照的地方创建更多的 memory_record 结构。问题是,如果我无法以某种方式记录实际使用了多少内存,则此内存资产负债表记录将无济于事。
但是我该怎么做呢?另外,我将如何考虑悬空指针和泄漏?我正在使用 OS X,我目前正在查找如何记录堆栈指针和其他内容。
编辑:既然你问:valgrind的输出:(closure()是从main调用的返回错误指针的函数:它应该返回一个双向链表的头部,traversehashmap()是一个从closure()调用的函数我用来计算额外的节点并将其附加到链表中,它递归地调用自己,因为它需要在节点之间跳转。)
jason-danckss-macbook:project Jason$ valgrind --leak-check=full --tool=memcheck ./testc …Run Code Online (Sandbox Code Playgroud) 我在C中编写了一个悬挂指针的程序.
#include<stdio.h>
int *func(void)
{
int num;
num = 100;
return #
}
int func1(void)
{
int x,y,z;
scanf("%d %d",&y,&z);
x=y+z;
return x;
}
int main(void)
{
int *a = func();
int b;
b = func1();
printf("%d\n",*a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
即使指针悬空,我输出为100.
我在上面的函数中做了一个改动func1().现在我在编译期间分配值,y而z不是像上面的程序那样从标准输入中获取和从中获取值.
我重新定义func1()如下:
int func1(void)
{
int x,y,z;
y=100;
z=100;
x=y+z;
return x;
}
Run Code Online (Sandbox Code Playgroud)
现在输出是200.
有人可以解释一下上述两项产出的原因吗?
dangling-pointer ×10
c ×5
c++ ×5
pointers ×5
memory ×2
c++11 ×1
c++23 ×1
coroutine ×1
double-free ×1
heap-memory ×1
memory-leaks ×1
stl ×1
vector ×1