C++新手,一直在编写C++程序,但它最终在从 ctime 调用 lib 函数调用时中断。
错误显示如下信息:
malloc((:内存损坏
AFAIK,此错误(内存损坏(应由对越界内存地址进行操作导致。打印格式表示 YYYY-MM-DD-HH-MM,此处列出的显示长度应明确小于 100。
附加信息:
- 该程序使用标志编译:"-O3 -g -Wall -Wextra -Werror -std=c++17">
- 编译器:g++ 7.4.0
- 系统:WSL Ubuntu-18
注意:此代码无法编译,并且无法重现该问题,请参阅下面的更新
/** class file **/
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <ios>
#include <fcntl.h>
#include <algorithm>
#include <cctype>
#include <ctime>
#include <limits>
#include "cache-proxy.hpp"
static int PROXY_CONFIG = 0;
void get_timestamp(char *buffer, int len);
std::string get_cwd(void);
CacheProxy::CacheProxy(__attribute__((unused)) const std::string& node)
{
curr_dir = fs::get_cwd();
Logger::get().info("curr_dir " + curr_dir);
proxy_path = "/usr/sbin/squid";
std::string squid("squid");
char buff[200];
get_timestamp(buff, 200); // error pops
std::string proxy_config_path;
/** plenty of codes following, but commented**/
}
void ~CacheProxy(){}
void get_timestamp(char *buffer, int len)
{
time_t raw_time;
struct tm *time_info;
time(&raw_time);
time_info = std::localtime(&raw_time);
std::strftime(buffer, len, "%F-%H-%M", time_info);
return;
}
// originally from other files, for convenient to be moved into this file
std::string get_cwd(void)
{
char path[PATH_MAX];
std::string retval;
if (getcwd(path, sizeof(path)) != NULL) {
retval = std::string(path);
} else {
Logger::get().err("current_path", errno);
}
return retval;
}
/** header file **/
#pragma once
#include <string>
class CacheProxy:
{
private:
int server_pid;
std::string proxy_path;
std::string curr_dir;
std::string squid_pid_path;
;
public:
CacheProxy(const std::string&);
~CacheProxy() override;
};
/** main file **/
int main(){
Node node(); // the parameter is never used in the CacheProxy constructor though
CacheProxy proxy(node); // error pops
proxy.init();
}
感谢您的任何建议或想法。
更新:
代码更新如上,有三个主要文件。代码通过省略不相关的代码来显示与我的原始代码库逻辑完全相同的序列(我在遇到错误时将它们注释掉(,但请原谅我给出如此粗略的代码。
基本上,错误在对象初始化期间弹出,我目前假设问题要么在get_cwd,要么在当地时间。
请指出您是否需要更多信息,尽管我认为其他代码确实无关紧要。
12月21日更新:
在注释掉原始代码的不同部分后,我设法找到了错误部分,但无法修复错误。评论中的意见确实是正确的,内存损坏错误应该源于事先的某个地方,但是,我将要做的解决这个问题的方法与其他答案有些不同,因为我为我的程序使用 setcap 并且在这种情况下无法使用 valgrind。
我使用了另一个称为ASan(地址清理器(的工具进行内存检查。使用该工具很容易找出内存损坏的来源,并且在运行时发生错误时,它具有全面的分析。我在编译器中添加了支持,发现我的情况的主要问题是 CacheProxy 类中字符串变量的内存分配。
到目前为止,它已被证明是另一个问题,即"为什么在以下情况下为字符串对象分配内存会产生间接内存泄漏 这个类的构造函数被称为",我不会在这个问题中折叠它。
但这对我来说真的是一个很好的教训,内存问题实际上有多种类型和原因,你不能盯着源代码来解决一个不是"索引越界"或"非法地址访问"(段错误(问题的问题。许多工具非常方便,专门处理这些事情,所以去拿你的工具吧。
malloc 或 free 内部的任何崩溃都可能是早期堆损坏的原因。
您的记忆可能较早损坏。
如果你使用的是Linux,试着在valgrind下运行你的程序。Valgrind可以帮助您找出此类错误。
大卫提到的"明显的修复"是:
#include <iostream>
#include <ctime>
#include <cstdio>
void get_timestamp(char *buffer, int len)
{
time_t raw_time;
struct tm *time_info;
time(&raw_time);
time_info = localtime(&raw_time); // the line of code that breaks
strftime(buffer, len, "%F-%H-%M", time_info);
return;
}
int main() {
char buff[100];
get_timestamp(buff, 100);
std::cout << std::string(buff);
return 0;
}