将一个字符串转化成数组,使用malloc函数,编译正常,运行就崩溃!

guyanqiu 2010-01-13 11:41:32

/**************************
2010.01.13
版本 V0.1
用途:输入一个字符串,并转化为数组
*****************************/
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
int *zifu_shuzu(int length,char *zifu);
int main(void)
{
char *str;
int *shuzu;
int length;
int i;
printf("输入要转化的数字:\n");
scanf("%s",str);
length=strlen(str);
shuzu=zifu_shuzu(length,str);//程序执行到这里就会崩溃
for (i=0; i<length;i++)
printf("shuzu[%d]=%d \n",i,shuzu[i]);
if(shuzu!=NULL)
{
free(shuzu);
shuzu=NULL;
}
free(shuzu);
return 0;
}

//将一个字符串转化成十进制数表示的数组
int *zifu_shuzu(int length,char *zifu)
{
int i=0;
int *shuzu=(int *)malloc(sizeof(int)*length);//感觉好像是这里出问题了
for (i=0;i<length;i++)
{
if (zifu[i]>9)
shuzu[i]=zifu[i]-'A'+10;
else
shuzu[i]=zifu[i]-'0';
printf("转化输出为:%d",shuzu[i]);
}
return shuzu;
}
...全文
451 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
还是不明白,可是我这样用的时候正常啊?

#include<stdlib.h>
int main(void)
{

int len;//定义输入字符串的长度
char *str_in;//定义输入字符串的指针
char *pa;//定义数组a,用来装入字符
int i;
printf("输入要转换的数字:\n");
scanf("%s",str_in);//输入字符串
len = strlen(str_in);//计算输入字符串的长度
pa = (char*)malloc(len*sizeof(int));//分配内存给pa
pa = str_in;//将输入的字符串赋给数组
for(i=0;i<len;i++)
{
printf("pa[%d]=%c \n",i,pa[i]);//打印转化后的数组
}
printf("\n");
free(pa);//释放分配的内存
getch();
return 0;
}

jernymy 2010-01-13
  • 打赏
  • 举报
回复

*str是野指针,很容易导致程序崩溃

#include<stdio.h>
int main(void)
{
char str[100] = {0}; // char *str;
scanf("%s",str);
printf("你输入的是:%s",str);
getch();
return 0;
}

guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
还是不明白,书上讲的都看不怎么明白,所以我用的时候有的时候编译运行正常,有的时候就莫名其妙的退出,指针理解,但是不理解如何用?

#include<stdio.h>
int main(void)
{
char *str;
scanf("%s",str);
printf("你输入的是:%s",str);
getch();
return 0;
}

我试验了,这样的代码编译正常,可是,运行会退出?
那能说一下,错在哪里了么?
buptzwp 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 guyanqiu 的回复:]
那我试验一下给str申请内存,可是还是不明白,一般定义了 char *str;然后就可以直接给str赋值为字符串,这里为什么申请内存啊?
[/Quote]
这个要看看动态内存分配和理解什么是指针。
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
那我试验一下给str申请内存,可是还是不明白,一般定义了 char *str;然后就可以直接给str赋值为字符串,这里为什么申请内存啊?
caoshuming_500 2010-01-13
  • 打赏
  • 举报
回复
顶一下
buptzwp 2010-01-13
  • 打赏
  • 举报
回复
二楼给出答案了。
还有最后一个无关痛痒的free(shuzu);可以不用。
swl82560397pq 2010-01-13
  • 打赏
  • 举报
回复
很危险的野指针啊。
顶起
  • 打赏
  • 举报
回复
char *str;
int *shuzu;
int length;
int i;
printf("输入要转化的数字:\n");
scanf("%s",str); //str没申请内存,是野指针
hai040 2010-01-13
  • 打赏
  • 举报
回复
str没申请空间
if (zifu[i]>9)
if (zifu[i]>‘9’)
ssdx 2010-01-13
  • 打赏
  • 举报
回复

/**************************
2010.01.13
版本 V0.1
用途:输入一个字符串,并转化为数组
*****************************/
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
int *zifu_shuzu(int length,char *zifu);
int main(void)
{
char *str;
int *shuzu;
int length;
int i;
printf("输入要转化的数字:\n");
scanf("%s",str); ------------- str的空间在哪?
length=strlen(str);
shuzu=zifu_shuzu(length,str);//程序执行到这里就会崩溃
for (i=0; i<length;i++)
printf("shuzu[%d]=%d \n",i,shuzu[i]);
if(shuzu!=NULL)
{
free(shuzu);
shuzu=NULL;
}
free(shuzu);
return 0;
}

//将一个字符串转化成十进制数表示的数组
int *zifu_shuzu(int length,char *zifu)
{
int i=0;
int *shuzu=(int *)malloc(sizeof(int)*length);//感觉好像是这里出问题了
for (i=0;i<length;i++)
{
if (zifu[i]>9)
shuzu[i]=zifu[i]-'A'+10;
else
shuzu[i]=zifu[i]-'0';
printf("转化输出为:%d",shuzu[length-1-i]);
}
return shuzu;
}


guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
谢谢xianyuxiaoqiang的耐心解答。我就用你说的方法实验一下。
我看了33楼提供链接的野指针和悬浮指针的说明,基本明白了。具体使用还要研究一下。
xianyuxiaoqiang 2010-01-13
  • 打赏
  • 举报
回复
一般来说,接受用户输入必须预先分配固定大小的内存。要实现任意大小有几种解决方法:
1)提示用户输入一个数字来表示后续要输入多少字符,用这个数据来malloc内存

int count;
char * words = NULL;
printf("Please input your word count : \n");
scanf("%d", &count);
words = (char*)malloc(count);// 使用用户指定的大小
if( NULL == words ){
// 因为用户输入的数据可能是负数,也可能超过系统内存大小,很可能导致malloc失败,返回NULL
// 因此要出错处理
printf("Can't give you so much memery : %d \n", count);
return -1;// 退出当前函数
}
// 分配成功后,用words接受用户的输入,如果发生越界,可以进行出错处理,也可以让用户自食苦果...囧
...

2) 自己实现动态内存管理
#define MYSIZE 1024 // 预先定义内存块大小单位
...
char *pWords = NULL;// 用户输入缓冲
char *pTemp = NULL;// 备用缓冲
int size = MYSIZE;// 初始化内存块大小
int inputId = 0 ;// 当前输入的字节数
...
pWords = (char*)malloc(size);// 第一次分配内存
while(true){
// 使用scanf("%c",...)逐个字节循环接受用户输入
scanf("%c", &(pWords[inputId]));// 接受字符到 inputId 的位置
inputId++;// 下标增加
if(inputId >= size-1){
// 如果下个字符已经到了缓冲边界,需要开辟更大的缓冲
size += MYSIZE;// 缓冲大小增加一个单位
pTemp = (char*)malloc(size);// 篇幅有限,省略调用malloc的出错处理
memcpy(pTemp, pWords, size-MYSIZE);// 调用memcpy将旧缓冲的数据拷贝到临时缓冲中,注意缓冲的大小
free(pWords);// 将旧缓冲释放
pWords = pTemp;// 临时缓冲转正
pTemp = NULL;// 防止使用pTemp,因为它不是正宫……
}
// 无限接受用户输入,不断的循环……
}

guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
To xianyuxiaoqiang
char *s;//这个语句执行完之后,s很纳闷,它不知道自己的主人是谁
s =(char *)malloc(10);// 调用malloc向系统申请了10个字节的“堆内存”,把这个内存的地址告诉s,这时候s才安全了。
这个我理解了,函数中声明的变量是在栈中,函数从栈中调用,调用结束,函数返回值后,从栈中释放。而malloc是向系统申请的内存,函数结束后,内存没有被释放,而指针仍指向还占用着的内存。
free(s);// 调用free把s插着的内存还给系统,这时候占用着的内存释放了,但是指针还是指向已经释放了的内存
s = NULL;//让s沉睡吧 这时候把指针指向空,彻底释放调用过的内存,没有关联。
可我还有一个疑问,我11楼的程序可以执行,而1楼的不可以。
要怎么做使1楼的野指针正常工作?不预先定义数组的大小,要动态定义。

就是怎么让9楼的字符串正常输入赋值,而不采用10楼的固定大小的方法?必须要定义出大小么?
xianyuxiaoqiang 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 guyanqiu 的回复:]
char *str=s;    //这样是把栈上的内存赋值给指针str 这句我不理解

char *str=(char *)malloc(10*sizeof(char) );    //这是在堆上申请10个字节不理解

你直接char *s;  //只是声明了一个指针s,这个s存在栈上。但是s本身的值被我们认为是一个虚拟地址,如果你不申请内存,这个是无效的,所以是野指针。这个也不是很明白
[/Quote]
这里就有栈和堆两个概念了。
简单点说,栈就是一块连续的区域,分配内存符合后进先出法则,进,只需声明变量,出,一般是退出函数时由函数自动释放。堆是由操作系统管理的不连续的区域,C语言由malloc函数向系统申请,必须与free函数配合使用,函数退出时一般不会自动释放堆内存。
至于指针,它只是一根针,它上面挂着什么它事先是不会知道的。必须由我们自己告诉它。
char *s;//这个语句执行完之后,s很纳闷,它不知道自己的主人是谁
s =(char *)malloc(10);// 调用malloc向系统申请了10个字节的“堆内存”,把这个内存的地址告诉s,这时候s才安全了。
free(s);// 调用free把s插着的内存还给系统
s = NULL;//让s沉睡吧
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 suchx 的回复:]
我感觉,你可以看下书的,^_^。看完书后理解更好些。否则系统给你提示“该内存不能为读”,可能又会产生新的疑问了。虽然工作忙,还是请有空的话看看C方面的书和系统方面的书,不需要很多时间的。CSAPP就不错,不过可能有一点厚。
[/Quote]
我现在的工作很有空 ,不然纯粹硬件的工作,也不会去学C了。说实话,看书真的不如实际动手,而且书上也有错的。
我记得好像是谭浩强的C++程序设计吧,第一章例1.4,那个把分数98.5(好像是,在公司没有书看,书在宿舍)赋值给一个结构的整型变量,完全按照他的程序写的,可是按照他的输入得不到他的输出,要输入整型的数才可以正常输出,不然下一个结构数据输出全是0。我用的GCC编译器。
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 xianyuxiaoqiang 的回复:]
说"可能"因为不是每次都会引起进程甚至系统崩溃的,发生什么还是取决于该指针指向的地址值和对该指针进行的操作。

PS:你想研究病毒么?
[/Quote]
不想,除了破坏普通人的电脑,真看不出来病毒很有作用,要是有人用病毒控制了卫星,干点中国人都开心的事情,那我一定用崇拜的目光向搞病毒的致敬!
都是熊猫烧香的话,就只有鄙视了!
suchx 2010-01-13
  • 打赏
  • 举报
回复
我感觉,你可以看下书的,^_^。看完书后理解更好些。否则系统给你提示“该内存不能为读”,可能又会产生新的疑问了。虽然工作忙,还是请有空的话看看C方面的书和系统方面的书,不需要很多时间的。CSAPP就不错,不过可能有一点厚。
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 suchx 的回复:]
http://en.wikipedia.org/wiki/Dangling_pointer
可以先简单看看,有个概念,或者问问同事也可以的
[/Quote]
谢谢,英语不好,够看两天的了。同事都是搞硬件的,很纯粹的硬件,呵呵。同学不少搞软件的,不过天天都是太忙。我本科就出来了,他们都今年(应该说去年了)刚毕业。
有时候自己看书,不如别人指点一个操作。
我以前用Matlab拟合一个三维的曲面,看书上网一整天,没搞定,我同学过来找我吃饭的时候,他动了动鼠标,5分钟不到,解决了。
guyanqiu 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 xianyuxiaoqiang 的回复:]
引用 31 楼 guyanqiu 的回复:
呵呵,我经常在Ubuntu上面试,

都在讲野指针的危害,可是我还是不知道怎么让野指针不野?

有个很简单的办法:

C/C++ codechar* ptr= NULL;//任何时候申请一个指针时都做这个操作
C/C++ codefree(p);
p= NULL;// 任何时候释放了一块内存后就把指针置为NULL
一般来说,系统对于NULL指针都是有防护的。
[/Quote]

谢谢!这个比较实际一些。就是在申请的时候顺便赋值了,不让它随机赋值。
加载更多回复(23)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧