malloc的问题,太诡异了

soulmachine 2007-09-10 09:02:13
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void upcase(char *oldstr, char *newstr);

int main(void)
{
char *string = NULL;

upcase("Hello", string);
printf("str1=%s \n", string);
free(string);

upcase("Goodbye", string);
printf("str2=%s\n", string);
free(string);

return 0;
}

void upcase(char *oldstr, char *newstr)
{
int i;

newstr = malloc(strlen(oldstr) + 1);
strcpy(newstr, oldstr);
printf("%s\n",newstr);

for (i = 0; i < strlen(newstr); i++)
{
newstr[i] = toupper(newstr[i]);
}
return;
}
执行结果是:
Hello
str1=(null)
Goodbye
str2=(null)
为什么是这样子?
...全文
1663 89 打赏 收藏 转发到动态 举报
写回复
用AI写文章
89 条回复
切换为时间正序
请发表友善的回复…
发表回复
danielxin 2012-08-10
  • 打赏
  • 举报
回复
CSYNYK对内存还是有比较深的研究。但是这个问题上。。。。
赵破奴 2011-10-21
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 zyx040404 的回复:]

void upcase(char *oldstr, char *newstr)
改成void upcase(char *oldstr, char **newstr)
多加一个*
[/Quote]为什么呢?
赵破奴 2011-10-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 chiyer 的回复:]

// C2.cpp : Defines the entry point for the console application.
//


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void up……
[/Quote]void upcase(char *oldstr, char **newstr); 为什么newstr要用指针的指针啊?求教...求教...
pdszcxhh 2011-10-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 soulmachine 的回复:]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void upcase(char *oldstr, char *newstr);

int main(void)
{
char *string = NULL;

upcas……
[/Quote]

同意
hhsyxxwl0601 2011-10-21
  • 打赏
  • 举报
回复
LZ还没有搞明白形参和实参是什么东东
看下书吧,这些基础的东西还是需要自己先学习的
赵4老师 2011-10-21
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
绿野耕夫 2011-10-21
  • 打赏
  • 举报
回复
to CSYNYK

你这个版块的分是刷出来的吧?
回去好好研究下指针和按值传递规则吧,不要一碰到问题就觉得是编译器的问题。

lida2003 2011-10-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sniperhuangwei 的回复:]

void upcase(char *oldstr, char *newstr)
改成
void upcase(char *oldstr, char **newstr)

如果是C++也可改成传指针引用.
[/Quote]

正解!,参数传递的是指针的指针才能把内部指针内容产地出来。
lauxp 2007-10-26
  • 打赏
  • 举报
回复
include <stdio.h >
#include <string.h >
#include <stdlib.h >
#include <ctype.h >

char* upcase(char *oldstr);

int main(void)
{
char* string = upcase("Hello");
if (string)
{
printf("str1=%s \n", string);
free(string);
string = 0;
}
string = upcase("Goodbye");
if (string)
{
printf("str2=%s\n", string);
free(string);
}
return 0;
}
char* upcase(char *oldstr)
{
int i;
char * newstr = (char*)malloc(strlen(oldstr) + 1);
if (newstr)
{
strcpy(newstr, oldstr);
for (i = 0; i < strlen(newstr); i++)
{
newstr[i] = toupper(newstr[i]);
}
return;
}
return newstr;
}

我说垃圾是不对,不过你们的分析确实让我很失望,很简单的一个问题都搞到哪里去了,基本功,各位大学生们
wishfly 2007-09-20
  • 打赏
  • 举报
回复
不要讨论那没多,只要记住一点就可以了:
---从函数中获得分配来的指针,用**p.

wishfly 2007-09-20
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void upcase(char *oldstr, char **newstr);

int main(void)
{
char *string = NULL;

upcase("Hello", &string);
printf("str1=%s \n", string);
free(string);

upcase("Goodbye", &string);
printf("str2=%s\n", string);
free(string);

return 0;
}

void upcase(char *oldstr, char **newstr)
{
int i;

*newstr = (char *)malloc(strlen(oldstr) + 1);
strcpy(*newstr, oldstr);
printf("%s\n",*newstr);

for (i = 0; i < strlen(*newstr); i++)
{
(*newstr)[i] = toupper((*newstr)[i]);
}
return;
}
lihao1111111111 2007-09-20
  • 打赏
  • 举报
回复
CSYNYK() ( ) 信誉:100 分析的正确!

问题出在使用了空指针做为参数!
JackyRao 2007-09-20
  • 打赏
  • 举报
回复
void upcase(char *oldstr, char *newstr)
该为void upcase(char *oldstr, char **newstr)
_石头_ 2007-09-14
  • 打赏
  • 举报
回复
to sniperhuangwei()
呵呵!没办法啊!现在流行欠债的是大爷阿!---不过楼主给我的感觉还不错,上次我给他解答过一个问题!
tiancai1(ok)
讨论了这么多,同样的问题每个人都有不同的理解,其实有一个最根本的解决办法,那就是看汇编代码,虽然繁杂但执行过程最简单。
汇编里面所有的寻址都只有这几种情况:段内和段外
1、段内 只计算偏移量
2、段外 段地址+偏移量
(c指针所指向的就是这些内容,也就是因为指针能直接操纵地址偏移,所以才有这么大的能力和魅力)所有的内存(除了cpu寄存器以外)也只有两种1、ROM ,2、RAM,至于这个区那个区的就是段的范畴了。
所以我觉得(个人见解,不见得完全正确),不管哪一种语言或者是哪一种编程方式只要能在汇编里面验证通过,我觉得就是对的,同样的问题有很多种处理方法,只是方法的完善程度和效率的高低问题,反过来也一样对于不明白的问题,也不妨多参考一下汇编的代码,这样才不至于得出“己所不知,责人甚愚”!
tiancai1 2007-09-14
  • 打赏
  • 举报
回复
看了后确实思考了一些东西!!!
sniperhuangwei 2007-09-14
  • 打赏
  • 举报
回复
CSYNYK老兄,现在的人都不结贴.啥年代才能混到三裤叉啊.
_石头_ 2007-09-14
  • 打赏
  • 举报
回复
顺便问一下,笨笨前辈,请问c程序的汇编代码能不能验证c程序的执行情况阿?
_石头_ 2007-09-14
  • 打赏
  • 举报
回复
248406869(笨笨)
呵呵!向你学习!
248406869 2007-09-14
  • 打赏
  • 举报
回复
CSYNYK(),你不懂C,请不要胡说八道.
yinwhite 2007-09-14
  • 打赏
  • 举报
回复
CSYNYK() 的什么地址分配完全是错误!
下面的代码是最这个函数初终想法的最好实现,在VC6.0下通过!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

char* upcase(char *oldstr, char **newstr);

int main(void)
{
char *string = NULL;

upcase("GoodbyeGoodbyeGoodbyeGoodbyeGoodbyeGoodbyeGoodbyeGoodbye", &string);
printf("str1=%s \n", string);
free(string);

upcase("HelloHello", &string);
printf("str2=%s\n", string);
free(string);

getchar();
return 0;
}

char* upcase(char *oldstr, char **newstr){
unsigned int i;

*newstr = malloc(strlen(oldstr) + 1);
strcpy(*newstr, oldstr);
printf("%s\n",*newstr);

for (i = 0; i < strlen(*newstr); i++){
(*newstr)[i] = toupper((*newstr)[i]);
}
return *newstr;
}
加载更多回复(70)

69,373

社区成员

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

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