c语言,访问空指针

bbaimu
  • 694
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct string 
{
    int flag;//符号位
    char *str;
    int length;//字符串长度

}string;

typedef string Elemtype;

typedef struct node
{
    Elemtype data;
    struct node *next;
}node, *pnode;

void showElem( pnode list )
{
    pnode p = list->next;
    puts( "123" );
}

int main( void )
{
    pnode list;
    list = ( pnode ) malloc( sizeof(node) );
    list->next = 0;
    showElem(list); //正常访问

    char buf[120];
    char *str;
    string s;

    gets( buf );
    str = ( char* )malloc( sizeof(buf) + 1);
    s.flag = 1;
    strcpy( buf, str );
    s.length = sizeof( buf ) - 1;

    showElem(list);  // 访问空指针,出错
    return 0;
}
showElem( ) 的作用只是想访问 list ->next
我明明在main函数中 给 list 分配空间,并且给 list ->next = 0 初始化
结果在showElem( ) 访问 list 却空指针报错

调试环境是VS2013
图片描述
图片描述

回复
阅读 4.4k
3 个回答

strcpy的原型是

char *strcpy(char *dest, const char *src);

从str拷贝到buf,意义不明,应该写反了?

还有两句showElem(list)之间没有对list进行操作

请给出详细的报错,你的报错说的是不允许的系统调用。

Debug

猜测:应该是因为你把 strcpy 的参数弄反了,将一个比 buf 的容量更大的缓冲区的内容复制到了 buf 中,导致 buf 溢出。buf 溢出的数据将 list 指针的值给『淹没』了。至于 buf 溢出的数据为何会淹没 lisp 指针的值,这与栈空间的分配机制有关,这方面的知识可以找一些进程内存布局的文章看。

要验证这个猜测是不是对,你可以在 vs 调试程序的过程中,观察 listlist->next 的值有没有变化。

我测试了你的程序,是像楼上说的那样,str实际上申请了121字节的内存,而buf只有12字节代码,如果在Main函数栈中,buf指针变量和list指针变量“挨”在一起的话(实际上也是这样),那么buf溢出的字节直接覆盖到了list变量那里,导致其改变。 直接测试list在strcpy前后是否发生改变即可判断。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏