To add to Adrian's answer while you code is correct the reason GCC is giving the warning is due to the explicit call to delete[]. I found that commenting out this line removed the warning. I think GCC is seeing the delete[] call in a bare-bones context (maybe because it is outside a destructor) and it thinks the memory might be freed while in use.
The warning persists if the code is moved to a purely C context (using malloc and free) with the gcc command, meaning it might be detecting frees (using either free() or delete[]) and warning you that data might be read/written after free (even though in this case its not). Could be a error with GCC not removing the copy it has of the char arrays pointer but I'm not too sure. There might be a GCC bug report on it but I couldn't find it. Here's the code I tested.
Note: GCC version: 11.3.0, minor increment but still persistent to GCC-11. I still used the same flags/options as your example.
#include <stdlib.h>
#include <stdio.h>
int main()
{
char* str = (char*)malloc(sizeof(char) * 64);
sprintf(str, "msg: %s", "hello world");
printf("%s\n", str);
free(str);
return 0;
}
When using g++ specifically though, if you use malloc and free it removes the warning for some reason. Here's the corresponding code:
#include <iostream>
#include <cstdio>
int main()
{
char* str = (char*)std::malloc(sizeof(char) * 64);
std::sprintf(str, "msg: %s", "hello world");
std::cout << str << std::endl;
std::free(str);
return 0;
}
Note: I used std::cout for consistency with your given code and because the warning persists if I used std::printf.
If you're using C++ specifically, you can use std::string.
#include <iostream>
#include <string>
#include <cstdio>
int main()
{
std::string str(64, ' '); ///< allocate a std::string with 64 characters, each initialised to a space (' ').
std::sprintf(&str[0], "msg: %s", "hello world"); ///< Get the pointer to the first value (C-style) by indexing the string and using the address operator (&)
std::cout << str << std::endl;
return 0;
}
The code above has no manual memory management, its done by std::string. Although I do get it if you're learning about the memory facilities in C++. Hopefully that's all clear.
Note: std::string's c_str() method wouldn't work here with std::sprintf because it expects a char* but c_str() returns a const char*.
Note: An yes, I know & can also be the reference operator or the bit-and operator but in this context it's used to obtain the address like in C.