我正在研究一些 C 代码,当我遇到以下代码段时:
struct example *example_clone(struct example *ex)
{
struct example *new_ex;
new_ex = ex + 1; // How does this works ?
....
new_ex = some_func(...); //makes new_ex as struct example
....
}
现在考虑new_ex = ex + 1;
new_ex就在记忆中的ex
之后吗?
如果在内存中ex
之后存在其他对象,该怎么办?它被替换了吗?
答案 0 :(得分:3)
该函数用一组struct example
个对象调用。
例如:
struct example bla[2] = { /* initializers */ };
example_clone(bla); // OK, bla[1] will be overwritten
这是正常的,因为ex + 1
指向现有对象。
但是将指针传递给对象而不是数组的元素是不行的:
struct example blo = { /* initializers */ };
example_clone(&blo); // Not OK, the object at &blo + 1 will be overwritten
这不行,因为ex + 1
未指向现有对象。函数执行将调用未定义的行为。
答案 1 :(得分:2)
将1
添加到指针意味着指向下一个元素`。请记住,指针指向某种类型的对象(它们不仅仅是编号的内存位置)。
例如,如果您指的是车场中的第一辆车,那么执行+1
意味着您指向第二辆车。
如果实际上没有其他对象,那么这很好,C有一个特殊情况,你可以指出一个超过现有对象的结尾。但是如果再次+1
会导致未定义的行为。
如果您尝试通读该指针并且那里没有对象,则会导致未定义的行为。只要您写入分配给您的内存,就可以通过指针进行写入。
答案 2 :(得分:2)
new_ex
刚好在记忆中的ex
之后吗?
是。它指向刚刚超过ex
结束的内存地址。
如果在内存之后存在其他对象,该怎么办?它被替换了吗?
将会发生以下两件事之一。首先,它可以覆盖那里的对象。其次,如果内存不可用,它可能会出现段错误。出于这个原因,我会认为这个功能是危险的。我会手动内联此代码,以便您可以验证ex + 1
的内容/存在。