我的程序/进程异常退出?我怀疑以下代码有问题:
有两个typedef TYPE1,TYPE2。 (TYPE1的大小比TYPE2大)
TYPE1 var1;
TYPE2 var2;
....
....var2 has been assigned.
....
memset(&var1, 0, sizeof(var1));
memcpy(&var1, (TYPE1 *)&var2, sizeof(TYPE1));
printf("....");
Cast var2可能会导致访问非法内存,从而导致分段错误?我认为它可能会破坏内存中var2之后的数据,但不能使分段错误?我发现我的程序在这里退出,因为以下printf()没有打印任何内容。
Cast会破坏内存中var2之后的数据,即使只读取它(var2只是memcpy()的来源。
如果我像memcpy(& var1,(TYPE1 *)& var2,sizeof(TYPE2))更改它会发生什么;
感谢。
答案 0 :(得分:1)
我。 可能导致分段错误,但不是因为您已经投放到(TYPE1*)
,而是因为您正在从{{1}阅读sizeof(TYPE1)
它也不会在var2
之后弄乱数据。实际上,您不必担心数据损坏。 Segmentation fault的目的是防止这种非法的内存访问,无论是读还是写
II。不会破坏var2之后的数据。 var2
的原型是
memcpy
观察`void * memcpy ( void * destination, const void * source, size_t num );`
。因此保证const
数据不会被修改。强制转换也无法决定它是否是无效的内存访问。您尝试复制的字节数,源和目标大小都很重要。
III。正如其他人所说,强制转换并不重要,在这种情况下,由于您从较小的数据结构复制到较大的数据结构,因此不会出现分段错误。
答案 1 :(得分:1)
首先:使用&var2
时,您无需将TYPE1*
投射到memcpy
。 memcpy
期望void*
,任何指针类型都可以转换为void*
。
这里的问题是,当TYPE1
大于TYPE2
并且您使用var2
作为大小将数据从var1
复制到sizeof(TYPE1)
时, memcpy最终会从var2
占用的内存中读取。因此,您正在访问不允许访问的内存。因此,分段错误是你可以获得的最好的错误,因为错误可能也会被忽视很长一段时间,直到它确实可能导致麻烦(未定义的行为是这里的关键短语)。
当您仅将sizeof(TYPE2)
个字节从var2
复制到var1
时,您可以在内存访问方面做得很好(只要TYPE1
真的大于{{1} }})。
答案 2 :(得分:0)
我相信这里错过了一个重要的观点。
你没有做更大或更短的指针。 int,char,float的所有指针都具有相同的大小并且只包含一个地址(当我们在16位DOS时间内在c中有近或远指针时,唯一的例外)。指针的大小与机器上的整数大小相同。
因此问题标题具有误导性。但你会问为什么我们需要带指针的类型呢?
当我们将一个指针从TYPE_1 *转换为TYPE_2 *时,我们基本上会告诉该指针指的是什么类型的变量,以及我们在编写实例时如何跳过它们
int * a;
a++; // skips four bytes if it is a 32 bit integer/machine
double *b;
b++; // skips 8 bytes