声明数组时[]和()之间的C++差异
C++ difference between [ ] and ( ) when declaring an array
有人能告诉我这两行C++代码之间的区别吗?
int *p = new int (7);
和
int *p = new int [7];
除了第一个它把数字7放在p[0]中之外,我看不出任何区别,还有其他区别吗?如果有char而不是int,会发生什么?
提前谢谢。
一个是7项的数组
new int [7]
另一个只是初始化一个指向值为7 的int的指针
int *p = new int (7);
逐个查看:int *p
创建一个指向int的指针。new int (7)
在堆上创建一个新的int,并将值7存储在那里。=
告诉计算机p
应该指向新创建的内部的地址
int *p = new int [7];
同样,将其逐个处理:我们已经知道int *p
创建一个指向int的指针。new int [7]
创建一个int
s的数组。该数组的大小为7,因此计算机为7个整数留出内存空间。在这种情况下,=
告诉指针它应该指向数组的开始,也就是说,它将指向这些int
s中的第一个。
当您将方括号[i]
与指针(例如p[i]
(一起使用时,您是在告诉计算机给您p
指向但偏移i
的内存地址。当p
指向数组的开头时,可以使用p[i]
访问数组的不同部分。但是如果p
指向一个int,那么p[i]
就没有意义了,所以它是未定义的。一种可能的结果是,它只会偏移内存地址,并为您提供存储在int旁边的内存中的任何信息,但行为是未定义的,因此不同的编译器、计算机、操作系统/任何东西都可能导致不同的结果。
第一个只创建一个int,而不是一个数组。试图访问它之外的任何内容,例如p[1]
,都是未定义的行为。
不幸的是,事实并非如此,我可以访问p[I]0上有值那里…-Raz Ben Netanel 29分钟前
这是你的下一个实验,但这只是一个学习练习!和往常一样,你不应该在家里尝试这个。
int t213(void)
{
// let me create an array of ints on the stack
int buff[128];
// and initialize them to a distinctive patterh
for (int i=0; i<128; i++) buff[i] = 0x55555555;
void* place0 = buff; // offset 0 into buff
// if you want, try printing buff[0] (and maybe 1 or 2 more)
// use hex to see the 55555555 pattern
// next I use placement new to do something that makes everyone
// (familiar with UB) uncomfortable ... Relax, I have an embedded
// software background and understand that the behavior we shall
// observe is not guaranteed, not even from 1 compile to the next
int* p1 = new (place0) int(7); // a single int, initialized to 7,
void* p1Addr = p1; // at location place0
// (no - I know your thinking about it, but don't do this.
// essentially because neither C nor C++ have memory layout symantics.)
dtbAssert(p1Addr == place0)(p1Addr)(place0); // no assert occurs
// both addresses are the same
// test the soup
std::cout << "np1 : " << std::setw(12) << std::hex << *p1 << " @" << DTB::hexComma(p1Addr)
<< "nbuff[0] : " << std::setw(12) << std::hex << buff[0] << " @" << DTB::hexComma(&buff[0])
<< "nbuff[1] : " << std::setw(12) << std::hex << buff[1] << " @" << DTB::hexComma(&buff[1])
<< std::endl;
// now spoil the soup:
p1[1] = 0xdeadbeef; // oops - UB NO COMPILER WARNING
// then test the soup once more
std::cout << "np1 : " << std::setw(12) << std::hex << *p1 << " @" << DTB::hexComma(p1Addr)
<< "nbuff[0] : " << std::setw(12) << std::hex << buff[0] << " @" << DTB::hexComma(&buff[0])
<< "nbuff[1] : " << std::setw(12) << std::hex << buff[1] << " @" << DTB::hexComma(&buff[1])
<< std::endl;
return(0);
}
由于我使用了一些私人工具,我将包括输出:
p1 : 7 @7ffe,c3bb,3910
buff[0] : 7 @7ffe,c3bb,3910
buff[1] : 55555555 @7ffe,c3bb,3914
p1 : 7 @7ffe,c3bb,3910
buff[0] : 7 @7ffe,c3bb,3910
buff[1] : deadbeef @7ffe,c3bb,3914
请注意标有注释"//oops-UB"的代码行。
该行使用p1[1]。但是编译器不会注意到越界索引,甚至不会发出警告。
因为它是UB,编译器生成了它想要的东西。在这种情况下(但不能保证(,就好像p1[1]存在——注意,buff[1]从55555555变为deadbeef
研究术语-退化指针
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数