代码之家  ›  专栏  ›  技术社区  ›  jeffpkamp

函数如何返回比其填充的字符数组大的cstring?

  •  1
  • jeffpkamp  · 技术社区  · 3 年前

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

    我在和 cstring C++中的库,用于从多个变量生成长字符串。我正在运行一个测试程序,以查看保存cstring所需的最大字符数组。为了做到这一点,我定义了 buffer 作为一个全局变量,我知道它的大小将保持cstring。生成后,我使用 strlen 找到最大长度,结果是1517年。然后出于好奇,当它失败时会是什么样子,我缩小了它的尺寸 缓冲器 到1000。。。它仍然有效。直到我减少了 缓冲器 到300。

    当我在 main() 函数,当 缓冲器 小于输出,但仍打印完整输出。包括我的工作示例,我使用了 gbuffer 缓冲器 用于全局版本的缓冲区和本地版本的缓冲区。

    我的假设是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;
    }
    
    1 回复  |  直到 3 年前
        1
  •  2
  •   Asteroids With Wings    3 年前

    我的假设是,cstring被写入内存,strcat在定义buffer或gbuffer时继续写入超过设置的界限,std::cout只是读取,直到它到达空字符,所以只要没有其他内容保留该空间或写入该空间,程序仍然可以运行,尽管无法保证它会运行,因为它在内存中写入而不是为它保留。

    对的

    您的程序行为未定义。

    不要这样做。