指针值为空作为函数参数传⼊
下⾯以⼀个例⼦来引出这种错误
下⾯以⼀个例⼦来引出这种错误:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
⼀个很简单的函数,就是给*p 在函数中分配空间并将p[0]置成1,最后打印输出p[0]。但是运⾏的结果却是segmengt fault 。我们通过查看这段程序的汇编代码来分析⼀下出现段错误的原因。
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string.h>
void func(int *p)
{
p = (int *)malloc(sizeof(int) * 10);
memset(p, 0, sizeof(p));
p[0] = 1;
}
int main()
{
int *p = NULL;
func(p);
cout << p[0] << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
重点放在
1
2
3
这两句汇编代码上。
sub $0x20,%rbp 的意思是给栈分配0x20⼤⼩的空间。
⽽mov %rdi,-0x18(%rbp)的意思是把函数的第⼀个参数的值压⼊栈中存储。
这说明了什么?说明了函数中的说明了函数中的*p 其实是⼀个临时变量,和主函数并不是同⼀个*p 了。
给临时变量申请内存并赋值当前不能反映到主函数的*p 上,所以主函数的*p 还是个空指针,⽽打印空指针当然就段错误了。Dump of assembler code for function func(int*):
0x00000000004008cd <+0>:    push  %rbp
0x00000000004008ce <+1>:    mov    %rsp,%rbp
0x00000000004008d1 <+4>:    sub    $0x20,%rsp
0x00000000004008d5 <+8>:    mov    %rdi,-0x18(%rbp)
0x00000000004008d9 <+12>:    mov    $0x28,%eax
0x00000000004008de <+17>:    mov    %rax,%rdi
0x00000000004008e1 <+20>:    callq  0x400780 <malloc@plt>
0x00000000004008e6 <+25>:    mov    %rax,-0x8(%rbp)
0x00000000004008ea <+29>:    mov    -0x8(%rbp),%rax
0x00000000004008ee <+33>:    mov    $0x8,%edx
0x00000000004008f3 <+38>:    mov    $0x0,%esi
0x00000000004008f8 <+43>:    mov    %rax,%rdi
0x00000000004008fb <+46>:    callq  0x400750 <memset@plt>
0x0000000000400900 <+51>:    mov    -0x8(%rbp),%rax
0x0000000000400904 <+55>:    movl  $0x1,(%rax)
0x000000000040090a <+61>:    leaveq
0x000000000040090b <+62>:    retq  End of assembler dump.
sub $0x20,%rbp
mov %rdi,-0x18(%rbp)
下⾯介绍两种解决⽅法:
1.函数返回临时指针的地址:
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string.h>
int* func(int *p)
{
//此时的p是个临时指针
p = (int *)malloc(sizeof(int) * 10);
memset(p, 0, sizeof(p));
p[0] = 1;
return p;  //返回地址
}
int main()
{
int *p = NULL;
p = func(p);
cout << p[0] << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2.传⼊指向指针的指针:
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string.h>
/
/*p存储的是main函数*ptr的地址
void func(int **p)
{
*p = (int *)malloc(sizeof(int) * 10);
sizeof 指针memset(*p, 0, sizeof(*p));
*p[0] = 1;
}
int main()
{
int *ptr = NULL;
func(&ptr);
cout << ptr[0] << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。 blog.csdn/Move_now/article/details/71944689⽂章标签:
个⼈分类:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。