我知道未初始化的局部变量是未定义的行为(UB),并且该值可能具有可能影响进一步操作的陷阱表示,但有时我想仅使用随机数进行可视化表示,并且不会在其他部分使用它们.例如,程序在视觉效果中设置具有随机颜色的东西,例如:
void updateEffect(){
for(int i=0;i<1000;i++){
int r;
int g;
int b;
star[i].setColor(r%255,g%255,b%255);
bool isVisible;
star[i].setVisible(isVisible);
}
}
Run Code Online (Sandbox Code Playgroud)
是不是比它快
void updateEffect(){
for(int i=0;i<1000;i++){
star[i].setColor(rand()%255,rand()%255,rand()%255);
star[i].setVisible(rand()%2==0?true:false);
}
}
Run Code Online (Sandbox Code Playgroud)
并且还比其他随机数发生器更快?
在Visual Studio中,我们都有"baadf00d",在运行时在C++中检查调试器中的变量时看到过"CC"和"CD".
根据我的理解,"CC"仅处于DEBUG模式,以指示内存何时是new()或alloc()并且是单元化的."CD"代表删除或免费内存.我在RELEASE版本中只看过"baadf00d"(但我可能错了).
偶尔会遇到内存泄漏,缓冲区溢出等问题,这些信息会派上用场.
是否有人能够指出何时以何种模式将内存设置为可识别的字节模式以进行调试?
我在Visual Studio 2008下调试一个(本机)多线程C++应用程序.在看似随机的场合,我得到一个"Windows触发了一个断点......"错误,并注意到这可能是由于堆.这些错误并不会立即使应用程序崩溃,尽管它很可能会在之后崩溃.
这些错误的一个大问题是它们只在实际发生损坏后弹出,这使得它们很难跟踪和调试,尤其是在多线程应用程序上.
什么样的事情会导致这些错误?
我该如何调试它们?
提示,工具,方法,启发......欢迎.
很久以前我曾经在C学校上学.我记得我真的讨厌C的东西:未分配的指针不指向NULL.
我问过包括教师在内的很多人为什么他们会将未分配指针的默认行为指向NULL,因为它似乎更难以预测.
答案应该是表现,但我从未买过.我认为,如果C默认为NULL,那么编程历史中的许多错误都可以避免.
这里有一些C代码指出(双关语)我在说什么:
#include <stdio.h>
void main() {
int * randomA;
int * randomB;
int * nullA = NULL;
int * nullB = NULL;
printf("randomA: %p, randomB: %p, nullA: %p, nullB: %p\n\n",
randomA, randomB, nullA, nullB);
}
Run Code Online (Sandbox Code Playgroud)
编译警告(很高兴看到C编译器比我在学校时更好)和输出:
randomA:0xb779eff4,randomB:0x804844b,nullA:(nil),nullB:(nil)
可以理解的是,将缓冲区错误输出(或创建溢出),但如果12字节缓冲区中使用的字节少于12个,会发生什么?是否有可能或者空尾随时都是0?正交问题可能会有所帮助:缓冲区在实例化但未被应用程序使用时包含哪些内容?
我在Visual Studio中查看了几个宠物程序,似乎它们附加了0(或空字符),但我不确定这是否是一个可能因语言/编译器而异的MS实现.
在各种代码中,我已经看到调试版本中的内存分配NULL...
memset(ptr,NULL,size);
Run Code Online (Sandbox Code Playgroud)
或者0xDEADBEEF......
memset(ptr,0xDEADBEEF,size);
Run Code Online (Sandbox Code Playgroud)
0xDEADBEEF,是否仍然不符合有效数据?我目前正在拆解Visual Studio 2012 Express中的一些小型C程序,我注意到了二进制文件中的一种趋势.
在main函数中执行的第一组指令总是:
SUB ESP,154 ; Doesn't have to be 0x154.
.....
.....
.....
LEA EDI,DWORD PTR SS:[EBP-154]
MOV ECX,55 ; Also doesn't have to be 0x55.
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
Run Code Online (Sandbox Code Playgroud)
那么,为什么机器用这个0xCCCCCCCC填充堆栈?我已经读过它被VC++或其他东西用作未初始化空间的标记?
然后让我说我要把一些东西放进我的缓冲区......编译器或处理器决定将它放在这个空间内的某个随机点,但是我不明白为什么它会把它放在那里......
EBP-90 > CCCCCCCC ÌÌÌÌ
EBP-8C > CCCCCCCC ÌÌÌÌ
EBP-88 > CCCCCCCC ÌÌÌÌ
EBP-84 > 00000001 ... ; Why this place?
EBP-80 > CCCCCCCC ÌÌÌÌ
EBP-7C > CCCCCCCC ÌÌÌÌ
EBP-78 > 41414141 AAAA ; Why this far from both the top …Run Code Online (Sandbox Code Playgroud) 鉴于这个用gcc 4.3.3编译的C代码
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
int * i;
i = (int *) malloc(sizeof(int));
printf("%d\n", *i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望输出是malloc()返回的内存中的任何内容,而输出是0. malloc是否将它返回的内存归零?如果是这样,为什么?
我刚刚注意到一些空主方法的奇怪的汇编语言代码.
//filename: main.c
void main()
{
}
Run Code Online (Sandbox Code Playgroud)
拆卸:
push ebp
mov ebp,esp
sub esp,0C0h; why on the earth is it reserving 192 bytes?
push ebx
push esi
push edi ; good compiler. Its saving ebx, esi & edi values.
lea edi,[ebp-0C0h] ; line 1
mov ecx,30h ; line 2
mov eax,0CCCCCCCCh ; line 3
rep stos dword ptr es:[edi] ; line 4
xor eax,eax ; returning value 0. Code following this line is explanatory.
pop edi ; restoring the original …Run Code Online (Sandbox Code Playgroud) C++标准是否保证未初始化的POD成员在新的位置后保留其先前的值?
或者更准确地说,根据C++ 11,下面的断言是否总能得到满足?
#include <cstdlib>
#include <cassert>
struct Foo {
int alpha; // NOTE: Uninitialized
int beta = 0;
};
int main()
{
void* p = std::malloc(sizeof (Foo));
int i = some_random_integer();
static_cast<Foo*>(p)->alpha = i;
new (p) Foo;
assert(static_cast<Foo*>(p)->alpha == i);
}
Run Code Online (Sandbox Code Playgroud)
C++ 03的答案是否相同?