-4
#include <stdio.h>
#include <string.h>

char lists[10][25];
char name[10];

void main()
{
    scanf("%s" , lists[0]);
    memcpy(name , lists[0], 25);

    printf("%s\n" , name);
}

在上面的代码中,我将字符数组“name”的大小预定义为 10。现在,当我将输入输入为:

输入 - abcdefghijklmnopqrstuvwxy

我得到的输出是相同的字符串:abcdefghijklmnopqrstuvwxy

我不应该得到输出:abcdefghij ???

即使数组的大小限制为 10,这如何成为可能?

4

2 回答 2

1

因为它不知道它正在写入的分配内存的大小,所以你逃脱了额外数据的写入位置。你可能不在另一个平台上,或者使用不同的编译器,或者不同的优化设置。

size参数传递给 时memcpy (),最好考虑目标内存的大小。

使用 char 数组时,如果您想更安全地避免内存溢出,可以使用strncpy (). 它将负责将尾随插入NULL正确的位置。

于 2017-10-28T17:42:42.647 回答
0

首先,数组是指针。例如,在 C 语言中,没有像 Java 那样的长度检查。

当您编写char a[2];操作系统时,您可以在内存上留出 2 个字符的空间。例如,让内存为

|1|2|3|4|5|6|7|8|9|10|11|12|
 a

a是指向地址 1 的指针。a[0] = 0;等于*(a+0) = 0,意思是write 0 to the address a + offset 0

因此,如果您尝试写入尚未分配的地址,可能会发生意想不到的事情。

例如,假设我们有char a[2];char b[2];并且内存映射是

|1|2|3|4|5|6|7|8|9|10|11|12|
 a   b

那么a[2] = 0等于b[0] = 0。但是如果这个地址是其他程序的地址,就会产生分段错误。

试试这个程序(它可能在没有编译器优化的情况下工作):

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

char a[4];
char b[4];

void main()
{
    scanf("%s" , a);    // input "12345678"
    printf("%s\n" , b); // print     "5678"
}

memcpy只需将您所说的数据大小从一个地址复制到另一个地址。

在您的示例中,您很幸运,因为您访问的所有地址都分配给了您的程序(在您的内存页面内)。

在 C/C++ 中,您有责任正确处理内存。另外,请记住字符串以 char 结尾,\0因此在数组char str[10];中我们通常有前 9 个字符和\0.

于 2017-10-28T17:57:57.893 回答