简体   繁体   English

C++ 动态 memory 分配怪异 output

[英]C++ dynamic memory allocation weird output

I'm learning about dynamic memory allocation in C++.我正在学习 C++ 中的动态 memory 分配。 On running the code below, different output is printed every time.在运行下面的代码时,每次都会打印不同的 output。

char *const dynamic_array = new char[50];
dynamic_array[0] = '\0';
dynamic_array[0] = 'a';
cout << dynamic_array << endl;
delete[] dynamic_array;

Example output(s) of 5 runs: 5 次运行的示例输出:

  • δ
  • δ
  • aⁿ
  • Γ
  • ε

why is the output different on some runs?为什么 output 在某些运行中有所不同?

This is unrelated to dynamic memory allocation but only to the legacy C string.这与动态 memory 分配无关,而仅与旧版 C 字符串有关。 A C string is a null terminated char array. C 字符串是null 终止的字符数组。 As you failed to properly write a null character ( '\0' ) after the 'a' , using it as a C string is undefined behaviour.由于您未能在'a'之后正确写入 null 字符( '\0' ),因此将其用作 C 字符串是未定义的行为。

The operator<< you are calling here:您在此处调用的operator<<

cout << dynamic_array << endl;

Expects a pointer to the first element of a null-terminated character array.需要一个指向以空字符结尾的字符数组的第一个元素的指针。 Your character array is not null-terminated, hence your code has undefined behavior.您的字符数组不是以空值结尾的,因此您的代码具有未定义的行为。

If you want a dynamically sized string you should write:如果你想要一个动态大小的字符串,你应该写:

std::string dynamic_array{"a"};
std::cout << dynamic_array;

This has nothing to do with dynamic memory allocation.这与动态 memory 分配无关。 Your code would have failed even if you had used a fixed local array without new[] :即使您使用没有new[]的固定本地数组,您的代码也会失败:

char fixed_array[50];
fixed_array[0] = '\0';
fixed_array[0] = 'a';
cout << fixed_array << endl;

You are calling the overloaded operator<< that takes a nul-terminated char* string as input, but you are simply putting the '\0' terminator in the wrong array element.您正在调用重载的operator<< ,它将一个以nul 终止的char*字符串作为输入,但您只是将'\0'终止符放在错误的数组元素中。

Use this instead:改用这个:

char *const dynamic_array = new char[50];
dynamic_array[0] = 'a';
dynamic_array[1] = '\0'; // <-- index 1, not 0!
cout << dynamic_array << endl;
delete[] dynamic_array;
char fixed_array[50];
fixed_array[0] = 'a';
fixed_array[1] = '\0'; // <-- index 1, not 0!
cout << fixed_array << endl;

In C++, variables and objects need to be declared and initialized , but depending on whether a particular variable is a local variable, a class-member variable or a global/static variable, their default initialization may be done by the compiler or not, following the rules described here: https://en.cppreference.com/w/cpp/language/default_initialization在 C++ 中,需要声明初始化变量和对象,但取决于特定变量是局部变量、类成员变量还是全局/静态变量,它们的默认初始化可能由编译器完成,如下此处描述的规则: https://en.cppreference.com/w/cpp/language/default_initialization

In short it means that local variables don't get default-initialized, while static/global variables get default-initialized.简而言之,这意味着局部变量不会被默认初始化,而静态/全局变量会被默认初始化。 What concerns to class member-variables, if there's no member-initialization syntax present in constructors (which is the case for the default-constructor), then they'll get default initialized as well.与 class 成员变量有关的问题是,如果构造函数中不存在成员初始化语法(默认构造函数就是这种情况),那么它们也会被默认初始化。

Another thing to remember regarding this uninitialized-variable issue and other undefined behaviors in C++ is that some compilers may decide (based on some heuristics or by default) to default-initialize all variables upon their declaration to avoid run-time logic errors, which may not always be desirable (mostly due to performance reasons), but it's possible to disable those.关于此未初始化变量问题和 C++ 中的其他未定义行为,要记住的另一件事是,某些编译器可能会决定(基于一些启发式或默认情况下)在声明时默认初始化所有变量以避免运行时逻辑错误,这可能并不总是可取的(主要是由于性能原因),但可以禁用它们。 A good starting point for reading about this is here: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/阅读此内容的一个很好的起点是: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM