c指针问题
这只是我心中的一个疑问 下面是代码c指针问题,c,pointers,C,Pointers,这只是我心中的一个疑问 下面是代码 main() { int *p,*q; int a =20; p = q; p = &a; free(p); printf("The values of p and q are %d and %d\n
main()
{
int *p,*q;
int a =20;
p = q;
p = &a;
free(p);
printf("The values of p and q are %d and %d\n",*p,*q);
}
我的疑问是,如果我们释放指针p,分配给该指针的内存将被释放并返回到可用内存池,因此在这种情况下,由于q也指向p,根据我的理解,取消引用q应该会产生错误。我说的对吗??
我在DeV C++编译器中运行这个程序,我惊讶的是它显示了指针的值。
在这种情况下,我们是否将指针q称为悬挂指针
提前多谢
Maddy如何从堆栈中释放内存
不计算 您试图在指向堆栈分配内存的指针上调用
free()
,这是未定义的行为,千万不要这样做。仅对从malloc()
获取的指针调用free()
a是一个自动变量,而applyinfree(p),其中p=&a是一个错误,您可能会在malloc其他内存时立即面对,因为您将其标记为不可用的空闲块内存。您应该阅读有关指针的内容并更好地理解它们
q
是一个未初始化的指针,您正在分配p
指向同一个未指定的内存区域
p = &a;
这没关系,现在p
包含a
的地址,但是q
仍然未初始化
free(p);
a
存储在堆栈中,而不是堆中。本可以通过以下方式实现:
int *a = malloc(sizeof(int)); // allocates memory and stores location
*a = 20; // modifies allocated memory
p = a; // have a second pointer to the same zone
free(p); // frees the allocated memory: now dereferencing either p or a is a sin.
尝试
释放未使用malloc
、calloc
或realloc
获取的内存会导致未定义的结果。有时它会做一些愚蠢的事情,比如继续跑步,然后给你愚蠢的结果。有时它会做一些更有用的事情:
$ ./a.out
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x00007fff8393bd5c ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7f7a30bc04b6]
./a.out[0x400526]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7f7a30b67d8e]
./a.out[0x400439]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 675233 /tmp/a.out
00600000-00601000 r--p 00000000 08:03 675233 /tmp/a.out
00601000-00602000 rw-p 00001000 08:03 675233 /tmp/a.out
00f04000-00f25000 rw-p 00000000 00:00 0 [heap]
7f7a30933000-7f7a30948000 r-xp 00000000 08:03 228559 /lib/libgcc_s.so.1
7f7a30948000-7f7a30b47000 ---p 00015000 08:03 228559 /lib/libgcc_s.so.1
7f7a30b47000-7f7a30b48000 r--p 00014000 08:03 228559 /lib/libgcc_s.so.1
7f7a30b48000-7f7a30b49000 rw-p 00015000 08:03 228559 /lib/libgcc_s.so.1
7f7a30b49000-7f7a30cc3000 r-xp 00000000 08:03 228962 /lib/libc-2.12.1.so
7f7a30cc3000-7f7a30ec2000 ---p 0017a000 08:03 228962 /lib/libc-2.12.1.so
7f7a30ec2000-7f7a30ec6000 r--p 00179000 08:03 228962 /lib/libc-2.12.1.so
7f7a30ec6000-7f7a30ec7000 rw-p 0017d000 08:03 228962 /lib/libc-2.12.1.so
7f7a30ec7000-7f7a30ecc000 rw-p 00000000 00:00 0
7f7a30ecc000-7f7a30eec000 r-xp 00000000 08:03 228501 /lib/ld-2.12.1.so
7f7a310cc000-7f7a310cf000 rw-p 00000000 00:00 0
7f7a310ea000-7f7a310ec000 rw-p 00000000 00:00 0
7f7a310ec000-7f7a310ed000 r--p 00020000 08:03 228501 /lib/ld-2.12.1.so
7f7a310ed000-7f7a310ee000 rw-p 00021000 08:03 228501 /lib/ld-2.12.1.so
7f7a310ee000-7f7a310ef000 rw-p 00000000 00:00 0
7fff8391d000-7fff8393e000 rw-p 00000000 00:00 0 [stack]
7fff839df000-7fff839e0000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
我的C库很有帮助地给出了失败的地址,并且非常有帮助地转储了内存映射(这对我来说是新的!谢谢!),这让我很快看到地址在堆栈上。尝试释放p
这里调用的-您只能释放malloc(或calloc,或realloc,或strdup)中的内容。在本例中,您将释放指向堆栈变量a
的指针,这是不允许的
这同样适用于取消引用*q
-q
中的值未初始化,因此取消引用也会导致未定义的行为。严格地说,p=q
也是未定义的*,但在实践中,简单地复制未初始化变量的值本身往往不会引起太多问题(只是不要期望该值有意义)
当您调用未定义的行为时,任何事情都可能发生-这包括但不限于:
- 马上坠毁
- 后来在一些不相关的代码中崩溃
- 在不崩溃的情况下损坏某些数据
- 损坏磁盘上一些您认为安全的数据
- 联系备份服务器并破坏备份
- 允许触发错误的黑客控制你的计算机
- 上述各项的任意组合
- 有时,什么也没有
编译器不需要给出任何类型的有用错误消息,尽管在某些情况下可能会这样做
简而言之,不要这样做,但如果你这样做了,不要期望它以任何一种特定的方式破裂。这类东西有一种很有趣的破坏方式,看起来就像是代码中完全不同部分的bug
*-根据C99 6.2.6.1,如果C实现具有指针类型的陷阱表示,则变量的未指定初始值可能是陷阱表示,在这一点上,通过q
lvalue读取它会调用未定义的行为。这给了我在运行Valgrind时所期望的确切行为:
==8839== Invalid free() / delete / delete[]
==8839== at 0x4024836: free (vg_replace_malloc.c:325)
==8839== by 0x8048440: main (boom.c:10)
==8839== Address 0xbe9a5164 is on thread 1's stack
我这么做是因为我很好奇,因为有几个人报告了同样的行为
p
(由free()
解除引用)的地址被称为悬挂指针,因此对其进行的任何操作都是未定义的。我编译时没有优化(-O0)和调试符号(-g),以生成更好的说明,但无论如何它都会崩溃
正如预期的那样,正常运行程序只会产生分段错误。在valgrind下分析时,程序实际上完成(当printf()
还取消引用爆炸指针时,会有其他投诉):
但这只是因为Valgrind抓住了SEGV
未定义的行为就是,未定义。这是可怕的“哇,在我的机器上工作!”错误的主要原因之一:)不要这样做free()
用于分配给malloc()
(及其朋友)的内存。当您按照预期使用glibc在gccIt segfaults中运行时,将出现分段错误。我已经发布了一个为什么的插图(通过Valgrind)来说明为什么。如果我像first p=&a;然后当你说p=q时,你分配p,而不是q<如果您不使用q=something
@leppie对代码进行初始化,那么code>q
将永远不会在您的代码中有效。Free实际上应该会释放p所指的内存。因此,当您删除q时,它应该正确地给出错误?如果我是,请更正我wrong@Maddy:free
仅释放malloc
分配的内存,对cve.mitre.org数据库的一个旧副本进行非常粗略的搜索,会发现软件中大约有60个漏洞是在释放和双重释放错误后使用的,可能还有另外4个导致漏洞的免费(空)错误。请确保您了解malloc()
和free()
的正确用法。
==8839== Invalid free() / delete / delete[]
==8839== at 0x4024836: free (vg_replace_malloc.c:325)
==8839== by 0x8048440: main (boom.c:10)
==8839== Address 0xbe9a5164 is on thread 1's stack
==8839== Use of uninitialised value of size 4
==8839== at 0x8048445: main (boom.c:11)
==8839==
The values of p and q are 20 and 459916161
==8839==
==8839== HEAP SUMMARY:
==8839== in use at exit: 0 bytes in 0 blocks
==8839== total heap usage: 0 allocs, 1 frees, 0 bytes allocated