G****u 发帖数: 51 | 1 有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC.
====== code ============
#include
int main() {
char *fun1(), *fun2();
printf("%s\n%s\n", fun1(), fun2());
return 0;
}
char *fun1() {
char str[]="ABC";
return (str);
}
char *fun2() {
char (*str)[]="ABC";
return (str);
} | c*******y 发帖数: 1630 | 2 嗯,return address from local.
但是不清楚为什么GCC接受第二个,第二个里面加条printf,第一个也变得有效了。
我一开始以为是inline掉了,加了-fno-inline-functions还是老样子。 | G****u 发帖数: 51 | 3 你说的两个都错, 是说的两个都return pointer to local variable么? 但我现在要弄
明白的不是这个return local variable的问题, 而是为啥2能输出正确的结果, 而1不能 | H****r 发帖数: 2801 | 4 这些code都哪里来的啊,看着让人眼晕...
【在 G****u 的大作中提到】 : 有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC. : ====== code ============ : #include : int main() { : char *fun1(), *fun2(); : printf("%s\n%s\n", fun1(), fun2()); : return 0; : } : char *fun1() { : char str[]="ABC";
| t****t 发帖数: 6806 | 5 事实上我刚才看花眼了, 第二个不能说是错, 但是类型不匹配. C可以强制转换.
char (*str)[]的意思是pointer to array of char, 而"ABC"被强制转换了.
【在 c*******y 的大作中提到】 : 嗯,return address from local. : 但是不清楚为什么GCC接受第二个,第二个里面加条printf,第一个也变得有效了。 : 我一开始以为是inline掉了,加了-fno-inline-functions还是老样子。
| G****u 发帖数: 51 | 6 如果你把两个fun()分开, 各写一个main(), 每个main里printf一个fun, 那么gcc里面
都能输出ABC, 但是同样的两个程序, 放到一些online c compiler里面, main+fun1 还
是输出garbage, main+fun2 输出ABC
【在 c*******y 的大作中提到】 : 嗯,return address from local. : 但是不清楚为什么GCC接受第二个,第二个里面加条printf,第一个也变得有效了。 : 我一开始以为是inline掉了,加了-fno-inline-functions还是老样子。
| G****u 发帖数: 51 | 7 yes, gcc will give warning for that.
【在 t****t 的大作中提到】 : 事实上我刚才看花眼了, 第二个不能说是错, 但是类型不匹配. C可以强制转换. : char (*str)[]的意思是pointer to array of char, 而"ABC"被强制转换了.
| t****t 发帖数: 6806 | 8 这个你必须不能弄明白. 你需要弄明白的是, undefined behavior may generate ANY
results, INCLUDING "it-sounds-like-correct" results.
不能
【在 G****u 的大作中提到】 : 你说的两个都错, 是说的两个都return pointer to local variable么? 但我现在要弄 : 明白的不是这个return local variable的问题, 而是为啥2能输出正确的结果, 而1不能
| c*******y 发帖数: 1630 | 9 对的,gcc的warning就是说指针类型不匹配的。
【在 t****t 的大作中提到】 : 事实上我刚才看花眼了, 第二个不能说是错, 但是类型不匹配. C可以强制转换. : char (*str)[]的意思是pointer to array of char, 而"ABC"被强制转换了.
| c*******y 发帖数: 1630 | 10 尽管如此,两者都还是return local啊。
只不过对auto的处理程度不一样吧。
【在 t****t 的大作中提到】 : 事实上我刚才看花眼了, 第二个不能说是错, 但是类型不匹配. C可以强制转换. : char (*str)[]的意思是pointer to array of char, 而"ABC"被强制转换了.
| | | G****u 发帖数: 51 | 11 问题是为啥fun2 总能输出ABC,而fun1时而能输出ABC(gcc), 时而输出garbage? array
在C里面到底是怎么给造出来的, 一下子可以等同与pointer, 一下子不能, 这背后的原
因是啥.
ANY
【在 t****t 的大作中提到】 : 这个你必须不能弄明白. 你需要弄明白的是, undefined behavior may generate ANY : results, INCLUDING "it-sounds-like-correct" results. : : 不能
| t****t 发帖数: 6806 | 12 fun2没有错, 所以总能输出ABC, 虽然你把好好的函数写成了一滩那什么.
fun1有错, 能不能输出ABC要看天意.
至于array和pointer的关系, 请仔细阅读C FAQ第6章.
【在 G****u 的大作中提到】 : 问题是为啥fun2 总能输出ABC,而fun1时而能输出ABC(gcc), 时而输出garbage? array : 在C里面到底是怎么给造出来的, 一下子可以等同与pointer, 一下子不能, 这背后的原 : 因是啥. : : ANY
| t****t 发帖数: 6806 | 13 1st one is returning pointer/reference to local, which is wrong
2nd one is returning value of local, which is correct.
BTW you don't say "return local", you say "return pointer/reference/address
of local"
【在 c*******y 的大作中提到】 : 尽管如此,两者都还是return local啊。 : 只不过对auto的处理程度不一样吧。
| c*******y 发帖数: 1630 | 14 BTW-taken,我前面是说的address的,后面就忘记了。这个我还是懂的:D
后面被强制转换了,所以safe?
address
【在 t****t 的大作中提到】 : 1st one is returning pointer/reference to local, which is wrong : 2nd one is returning value of local, which is correct. : BTW you don't say "return local", you say "return pointer/reference/address : of local"
| t****t 发帖数: 6806 | 15 第二个是pointer to string literal, pointer类型怎么转换都是string literal.
【在 c*******y 的大作中提到】 : BTW-taken,我前面是说的address的,后面就忘记了。这个我还是懂的:D : 后面被强制转换了,所以safe? : : address
| G****u 发帖数: 51 | 16 如果fun1改成fun3
char *fun3() {
char str[]="ABC";
char *p = str;
return (p);
}
address
【在 t****t 的大作中提到】 : 1st one is returning pointer/reference to local, which is wrong : 2nd one is returning value of local, which is correct. : BTW you don't say "return local", you say "return pointer/reference/address : of local"
| t****t 发帖数: 6806 | 17 错的...
【在 G****u 的大作中提到】 : 如果fun1改成fun3 : char *fun3() { : char str[]="ABC"; : char *p = str; : return (p); : } : : address
| G****u 发帖数: 51 | 18 那fun3里的return (p) 和 fun2里的 return(str) 啥区别? gcc没有报错也没有
warning
【在 t****t 的大作中提到】 : 错的...
| c*******y 发帖数: 1630 | 19 fun3=fun1
fun2=
char **str="abc";
return str;
【在 G****u 的大作中提到】 : 那fun3里的return (p) 和 fun2里的 return(str) 啥区别? gcc没有报错也没有 : warning
| d****i 发帖数: 4809 | 20 这个可以吗?
char *fun3()
{
char *str = "ABC";
return (str);
}
主程序里面可以打印出"ABC"吗?
【在 G****u 的大作中提到】 : 如果fun1改成fun3 : char *fun3() { : char str[]="ABC"; : char *p = str; : return (p); : } : : address
| | | G****u 发帖数: 51 | 21 char (*str)[] ="abc" <==> char **str="abc" ??
I dont know how you get this. But gcc actually gives warning for
char **str="abc". str is a pointer #1 which points to pointer #2 which
points string "abc"? but where is pointer #2?
【在 c*******y 的大作中提到】 : fun3=fun1 : fun2= : char **str="abc"; : return str;
| G****u 发帖数: 51 | 22 yes, this is a correct one.
【在 d****i 的大作中提到】 : 这个可以吗? : char *fun3() : { : char *str = "ABC"; : return (str); : } : 主程序里面可以打印出"ABC"吗?
| t****t 发帖数: 6806 | 23 strictly speaking, it's not equivalent. but in your case it's about the same.
as i said, char (*str)[] means "pointer to array of char", but that doesn't
matter as long as it is a pointer. let's say it's "pointer to T". then
forcefully convert string literal "ABC" (which has type "pointer to char")
to "pointer to T", then forcefully convert to back to "pointer to char". the
result will be the original pointer to char. it doesn't matter what is T,
wha matters is, str is a pointer to something.
【在 G****u 的大作中提到】 : char (*str)[] ="abc" <==> char **str="abc" ?? : I dont know how you get this. But gcc actually gives warning for : char **str="abc". str is a pointer #1 which points to pointer #2 which : points string "abc"? but where is pointer #2?
| G****u 发帖数: 51 | 24 I think it does matter what str points to. If it points to something in
function stack (destroyed after function exits), then return (str) is wrong,
just like what fun1 does. However, if it points to something that has a
storage duration throughout the lifetime of program, then it is correct,
just like char *str = "ABC".
This is why I cannot understand your explanation of why fun2 is correct. yes
,
the caller get the value (the address to something) of str, but if something
is stored in function stack, then its address is meaningless after
function exits. So what do you think str is pointing to in fun2 and where is
it stored?
Please correct me if I am wrong. Thanks.
same.
t
the
【在 t****t 的大作中提到】 : strictly speaking, it's not equivalent. but in your case it's about the same. : as i said, char (*str)[] means "pointer to array of char", but that doesn't : matter as long as it is a pointer. let's say it's "pointer to T". then : forcefully convert string literal "ABC" (which has type "pointer to char") : to "pointer to T", then forcefully convert to back to "pointer to char". the : result will be the original pointer to char. it doesn't matter what is T, : wha matters is, str is a pointer to something.
| t****t 发帖数: 6806 | 25 i didn't say fun2 is wrong, i said it's poorly written. dunno what you are
arguing.
in my previous post, i said as long as it's a pointer it should be ok
(albeit bad style). if it points to something in stack, it won't be
a pointer, it will be an array. an array is never a pointer.
wrong,
,
something
is
【在 G****u 的大作中提到】 : I think it does matter what str points to. If it points to something in : function stack (destroyed after function exits), then return (str) is wrong, : just like what fun1 does. However, if it points to something that has a : storage duration throughout the lifetime of program, then it is correct, : just like char *str = "ABC". : This is why I cannot understand your explanation of why fun2 is correct. yes : , : the caller get the value (the address to something) of str, but if something : is stored in function stack, then its address is meaningless after : function exits. So what do you think str is pointing to in fun2 and where is
| G****u 发帖数: 51 | 26 sorry, my bad, i want to say "your explanation of why fun2 is correct".
corrected in my post.
I am not arguing here, I just want to understand why fun2 is correct (or why
it is wrong if it is). I have spent hours on this.
【在 t****t 的大作中提到】 : i didn't say fun2 is wrong, i said it's poorly written. dunno what you are : arguing. : in my previous post, i said as long as it's a pointer it should be ok : (albeit bad style). if it points to something in stack, it won't be : a pointer, it will be an array. an array is never a pointer. : : wrong, : , : something : is
| G****u 发帖数: 51 | 27
if it points to something in stack, it won't be
You mean pointer cannot point to something in stack or you mean str in fun2
is not point to something in stack?
【在 t****t 的大作中提到】 : i didn't say fun2 is wrong, i said it's poorly written. dunno what you are : arguing. : in my previous post, i said as long as it's a pointer it should be ok : (albeit bad style). if it points to something in stack, it won't be : a pointer, it will be an array. an array is never a pointer. : : wrong, : , : something : is
| t****t 发帖数: 6806 | 28 basically, if str is a pointer, then only thing allocated for str is space
for a pointer. so naturally str won't point to anything on stack, because
there's nothing (except the pointer itself) there. it has to point to the
string literal, doesn't it?
so that's why i said as long as it is a pointer. the type of pointer doesn't
matter, for C all kinds of pointers can be converted back and forth.
but i repeat, an array is never a pointer. if str is an array, it will be
wrong.
why
【在 G****u 的大作中提到】 : sorry, my bad, i want to say "your explanation of why fun2 is correct". : corrected in my post. : I am not arguing here, I just want to understand why fun2 is correct (or why : it is wrong if it is). I have spent hours on this.
| t****t 发帖数: 6806 | 29 str in fun2(), of course.
fun2
【在 G****u 的大作中提到】 : : if it points to something in stack, it won't be : You mean pointer cannot point to something in stack or you mean str in fun2 : is not point to something in stack?
| G****u 发帖数: 51 | 30 yes, that is what I thought. If fun2 is correct, the only explanation would
be str points to string literal. I think char (*str)[] just does the same
thing as char *str="ABC".
thanks.
't
【在 t****t 的大作中提到】 : basically, if str is a pointer, then only thing allocated for str is space : for a pointer. so naturally str won't point to anything on stack, because : there's nothing (except the pointer itself) there. it has to point to the : string literal, doesn't it? : so that's why i said as long as it is a pointer. the type of pointer doesn't : matter, for C all kinds of pointers can be converted back and forth. : but i repeat, an array is never a pointer. if str is an array, it will be : wrong. : : why
| | | a9 发帖数: 21638 | 31 maybe he is asking where is "ABC" and why it's still there.
【在 t****t 的大作中提到】 : str in fun2(), of course. : : fun2
| r***t 发帖数: 21 | 32 in fun1, str is a local char array which has "ABC", the space is local stack.
in fun2, str is a poiner, "ABC" is treated as constant string, which will be
allocated from global space. | b***i 发帖数: 3043 | 33 代码写得对不对还得看你的目的,
你觉得fun2是对的,因为运行结果正常,那么你fun2的目的是什么?
【在 G****u 的大作中提到】 : 有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC. : ====== code ============ : #include : int main() { : char *fun1(), *fun2(); : printf("%s\n%s\n", fun1(), fun2()); : return 0; : } : char *fun1() { : char str[]="ABC";
| j*****I 发帖数: 2626 | 34 用gdb跟了一下,
(gdb) info locals
c1 = 0x7fff96489d80 "ABC"
c2 = 0x4005ff "ABC"
fun1()返回的str确实是stack的地址。如果在func1里面加个printf("%d",str);什么的
,好像这个stack里面的string就hold住了,main打印出来的就不是乱码了。
stack.
be
【在 r***t 的大作中提到】 : in fun1, str is a local char array which has "ABC", the space is local stack. : in fun2, str is a poiner, "ABC" is treated as constant string, which will be : allocated from global space.
| B********r 发帖数: 397 | 35
would
In fun1, str is array name of "ABC". When you return an array name whose
content was destroyed after returning, you can't get a right result.
In fun2, str is a pointer which points to an array "ABC". Since "ABC" is
constant and stays in the memory and what you return is the actual address,
you can find "ABC" in main(). (*str)[] just different from *str[] as a
pointer, instead of a pointer array.
【在 G****u 的大作中提到】 : yes, that is what I thought. If fun2 is correct, the only explanation would : be str points to string literal. I think char (*str)[] just does the same : thing as char *str="ABC". : thanks. : : 't
| p*********t 发帖数: 2690 | 36 fun1()在返回一个局部变量的地址,所以输出的是這個地址的值,因为fun1()的局部变
量在函数结束时消失,那个地址可能又被分配了新的值,所以是乱码。
要想输出abc,可以在fun1()的str设为static,这样即使fun1()函数结束,str[]还是在
内存存在。
char *fun1() {
static char str[]="ABC";
return (str);
}
有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC.
====== code ============
#include
int main() {
char *fun1(), *fun2();
printf("%s\n%s\n", fun1(), fun2());
return 0;
}
char *fun1() {
char str[]="ABC";
return (str);
}
char *fun2() {
char (*str)[]="ABC";
return (str);
}
【在 G****u 的大作中提到】 : 有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC. : ====== code ============ : #include : int main() { : char *fun1(), *fun2(); : printf("%s\n%s\n", fun1(), fun2()); : return 0; : } : char *fun1() { : char str[]="ABC";
| B********r 发帖数: 397 | 37 但我试了一下,如果在fun1里面用 char *str="ABC"确实就没问题了,如果局部变量消
失的话,这个str pointer不是应该也没法指向变量了么?还是说“ABC“属于const
variable所以不会随着返回而消失?
【在 p*********t 的大作中提到】 : fun1()在返回一个局部变量的地址,所以输出的是這個地址的值,因为fun1()的局部变 : 量在函数结束时消失,那个地址可能又被分配了新的值,所以是乱码。 : 要想输出abc,可以在fun1()的str设为static,这样即使fun1()函数结束,str[]还是在 : 内存存在。 : char *fun1() { : static char str[]="ABC"; : return (str); : } : : 有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC.
| d**********x 发帖数: 4083 | 38 normally "ABC" is stored in read only data area, which is safe to use.
but... i don't think it's a good idea to write program like that
部变
是在
【在 B********r 的大作中提到】 : 但我试了一下,如果在fun1里面用 char *str="ABC"确实就没问题了,如果局部变量消 : 失的话,这个str pointer不是应该也没法指向变量了么?还是说“ABC“属于const : variable所以不会随着返回而消失?
| p*********t 发帖数: 2690 | 39 如果你要定义一个数组,就用char str[]={'A','B','C'};
char *str="ABC";也可以。不过我狠少用。
"ABC"是一个string,你可以直接用string str=“ABC”;
【在 B********r 的大作中提到】 : 但我试了一下,如果在fun1里面用 char *str="ABC"确实就没问题了,如果局部变量消 : 失的话,这个str pointer不是应该也没法指向变量了么?还是说“ABC“属于const : variable所以不会随着返回而消失?
|
|