【问题标题】:How can function return a cstring larger than char array it is filling?函数如何返回一个大于它正在填充的 char 数组的 cstring?
【发布时间】:2021-01-04 16:33:40
【问题描述】:

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

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

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

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

#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;
}

【问题讨论】:

  • C++ 就像没有车道保险杠的保龄球。没有什么可以阻止您在数组范围之外进行写入。最糟糕的是,该程序可能仍然有效。但归根结底,未定义的行为是未定义的。

标签: c++ arrays c-strings


【解决方案1】:

我的假设是 cstring 被写入内存并且 strcat 在定义缓冲区或 gbuffer 并且 std::cout 只读取到它到达空字符时不断写入边界集,只要没有其他保留空间或写在那里,程序仍然可以运行,尽管不能保证它会,因为它是在没有为它保留的内存中写入。

正确。

您的程序的行为未定义。

不要这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2020-09-15
    • 2012-02-27
    • 1970-01-01
    相关资源
    最近更新 更多