将没有长度的指针作为目标传递到memcpy是否合法?

将没有长度的指针作为目标传递到memcpy是否合法?,c,pointers,memcpy,C,Pointers,Memcpy,我想知道我是否可以在memcpy中使用无长度的字符指针作为目标。 示例:我想将数据从定义长度的char数组复制到另一个数组中,但我想将其定义为没有特定大小的指针 char * ptr_1; char arr[4] = "Data"; memcpy(ptr_1, arr, 4); // IS it allowed to do this? 不,你不能那样做。如果您这样做,它将调用未定义的行为,因为ptr_1所指的地址位于行列式中,而您并不拥有它。此外,您还没有分配任何内存来保存来自arr的内容 您

我想知道我是否可以在memcpy中使用无长度的字符指针作为目标。 示例:我想将数据从定义长度的char数组复制到另一个数组中,但我想将其定义为没有特定大小的指针

char * ptr_1;
char arr[4] = "Data";
memcpy(ptr_1, arr, 4); // IS it allowed to do this?

不,你不能那样做。如果您这样做,它将调用未定义的行为,因为ptr_1所指的地址位于行列式中,而您并不拥有它。此外,您还没有分配任何内存来保存来自arr的内容

您可以为复制结果分配静态存储,也可以动态分配存储。memcpy的原型是

因此,对于静态分配的地址,您可以执行以下操作

#include <stdio.h>

int main(void) {
    char temp[5];
    char values[] = "Data";
    memcpy( temp, values, 4 );
    temp[4] = '\0';
    printf("%s\n", temp);
    return 0;
}
尽管memcpy的原型定义了源类型和目标类型使用void*,但C标准并不强制要求使用void*。指针可以在任何类型之间转换为void*,反之亦然。这就是为什么我们不把malloc的结果也作为案例的原因


您始终需要分配存储以在末尾包含空字符。如果使用空长度说明符(即值[])初始化数组,编译器将自动分配存储以在末尾包含空字符。对于像printf这样的库函数来说,打印字符串在理想情况下是希望字符串以空字符结尾。缺少它可能会触发未定义的行为,因为它不知道字符串的结尾是空字符。因此,在这两种情况下,请确保字符串的最后一个字节是空字符常量。

不,您不能这样做。如果您这样做,它将调用未定义的行为,因为ptr_1所指的地址位于行列式中,而您并不拥有它。此外,您还没有分配任何内存来保存来自arr的内容

您可以为复制结果分配静态存储,也可以动态分配存储。memcpy的原型是

因此,对于静态分配的地址,您可以执行以下操作

#include <stdio.h>

int main(void) {
    char temp[5];
    char values[] = "Data";
    memcpy( temp, values, 4 );
    temp[4] = '\0';
    printf("%s\n", temp);
    return 0;
}
尽管memcpy的原型定义了源类型和目标类型使用void*,但C标准并不强制要求使用void*。指针可以在任何类型之间转换为void*,反之亦然。这就是为什么我们不把malloc的结果也作为案例的原因

您始终需要分配存储以在末尾包含空字符。如果使用空长度说明符(即值[])初始化数组,编译器将自动分配存储以在末尾包含空字符。对于像printf这样的库函数来说,打印字符串在理想情况下是希望字符串以空字符结尾。缺少它可能会触发未定义的行为,因为它不知道字符串的结尾是空字符。因此,在这两种情况下,都要确保字符串的最后一个字节是空字符常量。

ptr_1是指针,指向任何东西,在随机位置执行memcopy会导致未定义的行为

在调用memcopy之前,必须将指针分配给有效地址

像这样,

char buf[4];
char * ptr_1 = buf;
char arr[4] = "Data";
memcpy(ptr_1, arr, 4); 
ptr_1是一个指针,指向任何东西,在随机位置执行memcopy会导致未定义的行为

在调用memcopy之前,必须将指针分配给有效地址

像这样,

char buf[4];
char * ptr_1 = buf;
char arr[4] = "Data";
memcpy(ptr_1, arr, 4); 

你的意图是什么?您希望将数据复制到哪里?为了得到有用的东西,你必须指定它。关于ptr_1,你唯一能说的是,它是一个未初始化的变量,可以包含一个内存位置的地址,当你试图读取它时,这个地址上的数据必须解释为一个字符。您可以为它分配一个静态数组的地址,或者一个具有有限生存期的本地临时数组的地址,或者为它分配一个调用malloc返回的地址,该地址在堆上分配,并通过调用free释放。由于写入一个未指定的随机地址是一件坏事,您必须用以下三种方法之一初始化它。您的目的是什么?您希望将数据复制到哪里?为了得到有用的东西,你必须指定它。关于ptr_1,你唯一能说的是,它是一个未初始化的变量,可以包含一个内存位置的地址,当你试图读取它时,这个地址上的数据必须解释为一个字符。您可以为它分配一个静态数组的地址,或者一个具有有限生存期的本地临时数组的地址,或者为它分配一个调用malloc返回的地址,该地址在堆上分配,并通过调用free释放。由于写入未指定的随机地址是一件坏事,因此必须使用以下三种方法之一对其进行初始化。printf%s\n,temp;调用UB。没有比这更简单的方法了:char temp[sizeof values];memcpytemp,value,sizeof value;,避免这些一个接一个的错误。printf%s\n,temp;调用UB。没有比这更简单的方法了 be char temp[sizeof values];memcpytemp,value,sizeof value;,避免这些一个接一个的错误。