以下代码是否合法?
char* randomMethod1() {
char* ret = "hello";
return ret;
}
Run Code Online (Sandbox Code Playgroud)
还有这个?
char* randomMethod2() {
char* ret = new char[10];
for (int i = 0; i < 9; ++i) {
ret[i] = (char)(65 + i);
}
ret[9] = '\0';
return ret;
}
Run Code Online (Sandbox Code Playgroud)
我会说第一个是合法的,因为你实际上正在做的是返回一个指向字符串文字的指针,我认为它是从程序的字符串表中加载的.但是,我会说第二个不是.我会在第二种方法中说你在堆栈上分配内存,一旦你离开函数,它可能被另一种方法使用,转向垃圾你要返回的指针.它真的有用吗?
编辑:好的,这是反汇编代码.任何人都可以解释我怎么能看到它被分配在堆上?
char* randomMethod2() {
000536E0 push ebp
000536E1 mov ebp,esp
000536E3 sub esp,0E4h
000536E9 push ebx
000536EA push esi
000536EB push edi
000536EC lea edi,[ebp-0E4h]
000536F2 mov ecx,39h
000536F7 mov eax,0CCCCCCCCh
000536FC rep stos dword ptr es:[edi]
char* ret = new char[10];
000536FE push 0Ah
00053700 call operator new (511E0h)
00053705 add esp,4
00053708 mov dword ptr [ebp-0E0h],eax
0005370E mov eax,dword ptr [ebp-0E0h]
00053714 mov dword ptr [ret],eax
for (int i = 0; i < 9; ++i) {
00053717 mov dword ptr [i],0
0005371E jmp randomMethod2+49h (53729h)
00053720 mov eax,dword ptr [i]
00053723 add eax,1
00053726 mov dword ptr [i],eax
00053729 cmp dword ptr [i],9
0005372D jge randomMethod2+5Fh (5373Fh)
ret[i] = (char)(65 + i);
0005372F mov eax,dword ptr [i]
00053732 add eax,41h
00053735 mov ecx,dword ptr [ret]
00053738 add ecx,dword ptr [i]
0005373B mov byte ptr [ecx],al
}
0005373D jmp randomMethod2+40h (53720h)
ret[9] = '\0';
0005373F mov eax,dword ptr [ret]
00053742 mov byte ptr [eax+9],0
return ret;
00053746 mov eax,dword ptr [ret]
}
00053749 pop edi
0005374A pop esi
0005374B pop ebx
0005374C add esp,0E4h
00053752 cmp ebp,esp
00053754 call @ILT+320(__RTC_CheckEsp) (51145h)
00053759 mov esp,ebp
0005375B pop ebp
0005375C ret
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 17
两者都是合法的.在第二个中,您没有从堆栈中分配内存.您正在使用new它并从堆中分配内存.如果你没有释放第二种方法返回的指针delete,你就会有内存泄漏.
顺便说一句,堆栈分配的数组声明如下:
char x[10]; // note that there's no `new`.
Run Code Online (Sandbox Code Playgroud)
该行调用operator new从堆中分配内存并初始化对象.
00053700 call operator new (511E0h)
Run Code Online (Sandbox Code Playgroud)
事实上两者都是合法的.在第二种情况下,您在堆中分配内存,而不是在堆栈上.这一行:
00053700 call operator new (511E0h)
Run Code Online (Sandbox Code Playgroud)
是一个operator new负责内存分配的调用.
堆栈上的分配如下:
char* randomMethod2() {
char ret[10];
....
return ret;
}
Run Code Online (Sandbox Code Playgroud)
确实会导致未定义的行为.
但是请不要忘记,在第一种情况下,尝试通过返回的指针修改内存也会导致未定义的行为.在第二种情况下,调用者负责释放内存(调用delete[]).
| 归档时间: |
|
| 查看次数: |
678 次 |
| 最近记录: |