return 一个比它正在填充的 char 数组大的 cstring 怎么运行?

How can function return a cstring larger than char array it is filling?

我想开始解释这只是一个好奇的问题,以帮助我更好地理解 c++。

我正在使用 C++ 中的 cstring 库从多个变量生成长 cstring。我是 运行 一个测试程序,用于查看我需要多少最大的字符数组来保存 cstring。为此,我将 buffer 定义为一个全局变量,其大小我知道可以保存 cstring。生成它后我用 strlen 找到最大长度,结果是 1517。然后出于好奇它失败时会是什么样子,我将 buffer 的大小减小到 1000...它仍然有效。直到我将 buffer 减少到 300.

才出现执行错误

当我在 main() 函数中定义缓冲区时,当 buffer 小于输出时我得到错误,但它仍然打印完整输出。我包括我的工作示例,我使用 gbufferbuffer 作为缓冲区的全局版本和缓冲区的本地版本。

我的假设是 cstring 被写入内存并且 strcat 继续写入超过定义缓冲区或 gbuffer 时设置的边界并且 std::cout 只是读取直到它遇到空字符,所以只要没有其他东西保留 space 或写在那里,程序仍然可以运行,但不能保证它会运行,因为它写入的内存不是为它保留的。

#include <iostream>
#include <cstring>

//Global Variables
int Temperature=100;
int Heat=100;
int Cool=100;
char Status[100]="Nothing";
char Source[100]="Default";
char gbuffer[900];

struct schedulePoint {
  uint8_t days = 12;
  uint8_t heat = 65;
  uint8_t cool = 85;
  uint16_t start = 60*24;
  uint16_t end = 60*24;
};

struct myData {
  char myName[12] = "TestStat";
  schedulePoint schedule[64];
  char password[25];
  char ssid[25] = "Wifi Thermostat";
  bool hidden = false;
  uint8_t defaultHeat = 65;
  uint8_t defaultCool = 85;
  int timezone = 0;
  char serverUName[25] = "";
  char serverPW[25] = "";
} data;


char * get_JSON(char * buff, unsigned int buffSize) {
  std::cout << "Buffer Size:" << buffSize << "\n";
  char convert[500];
  strcpy(convert,"<script>schedule=[");
  strcpy(buff,convert);
  for (uint8_t z = 0; z < 64; z++) {
    if (z == 0) strcat(buff, "[");
    else strcat(buff, ",[");
    sprintf(convert, "%d,%d,%d,%d,%d]", data.schedule[z].days, data.schedule[z].heat, data.schedule[z].cool, data.schedule[z].start, data.schedule[z].end);
    strcat(buff, convert);
  }
  strcat(buff, "];\n");
  sprintf(convert, "SSID=\"%s\";\n",data.ssid);
  strcat(buff, convert);;
  strcat(buff, "states=[\"Off\",\"Heating\",\"Cooling\"];\n");
  sprintf(convert, "stats={\"Temperature\":%d,\"State\":%s,\"Heat\":%d,\"Cool\":%d,\"Source\":\"%s\"};\n</script>", Temperature, Status, Heat, Cool, Source);
  strcat(buff, convert);
  return buff;
}


int main(){
        char buffer[1000];
        std::cout << get_JSON(gbuffer,sizeof(gbuffer));
        std::cout << "\n";
        std::cout << "Ouput Size:" << (unsigned)strlen(gbuffer);
        std::cout << "\n";
        return 0;
}

my hypothesis is that the cstring gets written to the memory and strcat keeps writing past the bounds set when buffer or gbuffer are defined and std::cout just reads until it hits the null char, so as long as nothing else reserves that space or is written there, the program still works out, though there is no guarantee that it will since it is writing in memory not reserved for it.

正确。

您的程序的行为未定义。

不要这样做。