2010-08-14 44 views
1

考虑下面的代码:复制串在C - 内存问题:

t[7] = "Hellow\0"; 
s[3] = "Dad"; 
//now copy t to s using the following strcpy function: 

void strcpy(char *s, char *t) { 
    int i = 0; 

    while ((s[i] = t[i]) != '\0') 
     i++; 
} 

上面的代码是从“C编程语言的书”拍摄。 我的问题是 - 我们复制7个字节到声明为3个字节。 我如何知道复制后,内存 中s []后的其他数据未被删除?

还有一个问题请:char *schar* s相同?

谢谢!

+0

本来我误解了这个问题。在全局作用域(例如't [7] =')你不能有表达式语句,你的函数参数s'和't'掩盖全局变量s'和't'。你从哪里得到这本书,肯定不是K&R的“The C Programming Language”。 – 2010-08-14 10:35:26

+0

请确保您的代码在发布之前进行编译。 – qrdl 2010-08-14 10:52:09

+0

你没有复制任何东西 - 没有调用strcpy函数。此外,函数中的s和t是提供的参数,与上面声明的t和s完全无关。 请提供完整的代码。 – Dipstick 2010-08-14 11:22:24

回答

2

正如您正确指出的那样,传递s[3]作为第一个参数将覆盖某些可能被别的方法使用的内存。最好你的程序会在那里崩溃,然后;在最坏的情况下,它会继续运行,受损,最终最终会破坏它应该处理的事情。

在C中执行此操作的预期方式是永远不会传递比所需时间短的数组。

顺便说一下,它看起来像你换了st;什么意思大概是这样的:到t[7]

void strcpy(char *t, char *s) { 
    int i = 0; 

    while ((t[i] = s[i]) != '\0') 
     i++; 
} 

现在,您可以复制s[4]使用该修正strcpy程序:

char t[] = "Hellow"; 
char s[] = "Dad"; 

strcpy(t, s); 

(编辑:的s的长度现在固定)

+0

明确指定终止的''\ 0''会给你留下比一个缓冲区更多的字符,因为C字符串总是自动以null结尾。 – 2010-09-20 11:23:08

+0

@Jon谢谢 - 修复。 – 2010-09-21 12:01:36

2

关于第一个问题。

如果幸运的话,您的程序将崩溃。

如果不是,它会继续运行并覆盖不应该被触摸的内存区域(因为您不知道那里实际是什么)。这将是一个地狱调试...

关于第二个问题。

char* s和char *s做同样的事情。这只是一个风格问题。

即,char* s可以被解释为“schar类型的指针”,而char *s可以被解释为“s是一个指向char”。但实际上,语法上它是一样的。

+2

除局部变量声明外,其中“char * a,b;”意想不到的结果。 – wj32 2010-08-14 10:36:43

+2

当然是:-))) – 2010-08-14 10:39:13

1

那例子什么都不做,你还没有调用strcpy。但是,如果你这样做:

strcpy(s,t); 

这将在几个方面是错误的:

  • 字符串小号不为空终止。在C中,strcpy可以知道字符串结束的唯一方法是找到'\ 0'。该功能可能认为s是无限的,它可能会破坏你的记忆并使程序崩溃。
  • 即使是空值终止的,正如你所说的小号大小是因为同样的原因只有3个,strcpy的会写内存到哪里小号末端,用可能带来灾难性的后果。

C语言的解决方法是在其中指定要复制的最大字符数的函数strncpy(dst,src,max)。仍然要注意的是,如果src短于个字符,该函数可能会生成非空终止的字符串。

+1

关于子弹#1:他是从't'_to_'s'复制的,所以不管是否是ntbs都不重要。所有它需要的是't'的空终止符。 – dirkgently 2010-08-14 10:45:03

1

我将假设st(在函数定义之上)都是char数组。

我怎么知道复制后,内存中s []后面的其他数据没有被删除?

不,这是更糟糕的,您正在调用未定义的行为,我们知道这是因为标准是这样说的。在s中的三个元素进行比较后,您可以执行所有操作。作业是一个严格的禁忌。进一步推进,你甚至不能进行比较。

还有一个问题请问:char s与char s相同吗?

在大多数情况下,除非您要声明/定义多个,否则您需要将一个变量粘贴到您要命名的每个变量上作为指针)。如果你定义

t[7] = "Hellow"; 
s[7] = "Dad"; 

你的榜样定义和崩溃不是

+0

感谢大家的答案。 – 2010-08-14 10:49:17

-1

字符串字面"Hellow\0"等于"Hellow"

+0

字符串文字“Foo”将具有内部表示{'F','o','o','\ 0'}但这不是问题无论如何... – 2010-09-21 12:12:07