在下面的代码中,不应将str_s指向堆栈中的某个位置。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* fun_s(){
char str[8]="vikash";
printf("s :%p\n", str);
return str;
}
char* fun_h(){
char* str = (char*)malloc(8);
printf("h :%p\n", str);
strcpy(str, "vikash");
return str;
}
int main(){
char* str_s = fun_s();
char* str_h = fun_h();
printf("s :%p\nh :%p\n", str_s, str_h);
return 0;
}
我知道在返回fun_s时存在问题,并且不能信任此指针的内容,但是根据我的理解,它应该指向堆栈中的某个位置而不是零?我在控制台中得到以下输出。您能解释一下为什么第三行打印(nil)而不是0x7ffce7561220
s :0x7ffce7561220
h :0x55c49538d670
s :(nil)
h :0x55c49538d670
GCC版本
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
作业系统:Ubuntu 18.04.3 LTS
您的编译器有意从该函数注入空返回值。我没有可用的gcc 7.4,但是我有7.3,并且我认为结果是相似的:
编译fun_s
为汇编可实现以下目的:
.LC0:
.string "s :%p\n"
fun_s:
push rbp
mov rbp, rsp
sub rsp, 16
movabs rax, 114844764957046
mov QWORD PTR [rbp-8], rax
lea rax, [rbp-8]
mov rsi, rax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0 ; ======= HERE =========
leave
ret
请注意,将硬设置为0到eax,这将在返回到调用方时保留结果指针。
使为str
静态可实现以下目的:
.LC0:
.string "s :%p\n"
fun_s:
push rbp
mov rbp, rsp
mov esi, OFFSET FLAT:str.2943
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, OFFSET FLAT:str.2943
pop rbp
ret
简而言之,您的编译器正在检测本地地址返回并将其重写为NULL。这样做可以防止以后对所述地址的任何恶意使用(例如:内容注入攻击)。
我看不出有任何理由编译器应该不会被允许这样做。我相信语言纯粹主义者会证实或拒绝这种怀疑。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句