我有一个程序可以记录来自串口的数据。每隔一段时间,我就想分割文件,使数据日志不会变得非常大。问题是,在我重新创建FILE *并尝试写入它之后,程序崩溃了。之前没有编译器错误/警告...
程序会在第一个时间间隔创建一个日志,但是一旦创建新数据日志,它就会在fwrite崩溃。
首先,初始化/声明。
char * DATA_DIR = "C:\DATA";
sprintf(path,"%s%s%s",DATA_DIR,curtime,".log"); //curtime is just the current time in a string
FILE * DATA_LOG = fopen(path, "wb+");
稍后在一个循环中
if(((CURRENT_TIME-PREVIOUS_TIME) > (SEC_IN_MINUTE * MINUTE_CHUNKS) ) && (MINUTE_CHUNKS != 0) && FIRST_TIME == 0) //all this does is just checks if its time to make a new file
{
fclose(DATA_LOG); //end the current fileread
char * path;
char curtime[16];
//gets the current time and saves it to a file name
sprintf(curtime , "%s" , currentDateTime());
sprintf(path,"%s%s%s",DATA_DIR,curtime,".log");
DATA_LOG = fopen(path, "wb+"); //open the new file
//just some logic (not relevant to problem)
PREVIOUS_TIME = CURRENT_TIME;
newDirFlag = 1;
}
fwrite(cdata , sizeof(char) , numChars , DATA_LOG); //crashes here. cdata, sizeof, and numChars don't change values
任何想法为什么会发生这种情况?我很难过。
答案 0 :(得分:1)
一些问题,路径没有分配内存(你正在写一些随机内存地址,这是坏事)。您还应该检查fwrite
fopen
的返回值是否有错误。如果有一次使用perror
,那么您就知道问题所在。很可能是fopen失败了,或者你写了path
来破坏你的筹码。
同样使用snprintf
它比仅仅sprintf
更容易受到缓冲区溢出的影响。
std::string
和fstream
呢?它们比你现在做的更安全(也可能更容易)。
答案 1 :(得分:0)
您的主要问题是char * path;
没有分配内存。这意味着您正在写入内存中的某些RANDOM [1]位置。
我建议您使用char path[PATH_MAX];
- 这样您就不必担心分配并随后为您的路径释放存储空间。
或者,您可以使用:
stringstream ss;
ss << DATA_DIR << currentDateTime() << ".log";
string path = ss.str();
fopen(path.c_str(), "wb+")
这是一个更加C ++风格的解决方案。
[1]随机而言,我并不是指一个真正的随机数,而是恰好位于堆栈中该位置的一些未知值。它几乎总是不是存储字符串的好地方。