赋值运算符中的 free() / delete / delete[] / realloc() 错误无效
Invalid free() / delete / delete[] / realloc() error in assignment operator
我是编程新手,当我尝试使用 Valgrind 运行程序时,我遇到了这样的错误。我用谷歌搜索了几个小时来解决这个问题。请你告诉我我哪里出错了。希望在赋值运算符附近有一些错误。
错误:
==5130== Invalid read of size 8
==5130== at 0x400CFD: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c040 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130== Invalid free() / delete / delete[] / realloc()
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D07: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c420 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D07: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130== Invalid free() / delete / delete[] / realloc()
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c040 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130==
==5130== HEAP SUMMARY:
==5130== in use at exit: 120 bytes in 1 blocks
==5130== total heap usage: 7 allocs, 8 frees, 729 bytes allocated
==5130==
==5130== Searching for pointers to 1 not-freed blocks
==5130== Checked 192,896 bytes
==5130==
==5130== 120 bytes in 1 blocks are still reachable in loss record 1 of 1
==5130== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x53C0024: getdelim (iogetdelim.c:66)
==5130== by 0x5444B52: getpass (getpass.c:97)
==5130== by 0x400F84: std::passwd::get() (passwd.c++:66)
==5130== by 0x400B3C: main (p1.c++:9)
==5130==
==5130== LEAK SUMMARY:
==5130== definitely lost: 0 bytes in 0 blocks
==5130== indirectly lost: 0 bytes in 0 blocks
==5130== possibly lost: 0 bytes in 0 blocks
==5130== still reachable: 120 bytes in 1 blocks
==5130== suppressed: 0 bytes in 0 blocks
==5130==
==5130== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
==5130==
==5130== 1 errors in context 1 of 3:
==5130== Invalid free() / delete / delete[] / realloc()
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c040 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130==
==5130== 1 errors in context 2 of 3:
==5130== Invalid free() / delete / delete[] / realloc()
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D07: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c420 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D07: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130==
==5130== 1 errors in context 3 of 3:
==5130== Invalid read of size 8
==5130== at 0x400CFD: std::passwd::~passwd() (passwd.c++:18)
==5130== by 0x400C06: main (p1.c++:21)
==5130== Address 0x5a1c040 is 0 bytes inside a block of size 8 free'd
==5130== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5130== by 0x400D16: std::passwd::~passwd() (passwd.c++:19)
==5130== by 0x400BFA: main (p1.c++:17)
==5130==
==5130== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
这是头文件 passwd.h
#include<stdio.h>
#include<iostream>
#ifndef MIN_PASSWD_LEN
#define MIN_PASSWD_LEN 6
#endif
#ifndef MAX_PASSWD_LEN
#define MAX_PASSWD_LEN 20
#endif
#ifndef NO_OF_NUMBERS
#define NO_OF_NUMBERS 1
#endif
#ifndef NO_OF_ALPHABETS
#define NO_OF_ALPHABETS 1
#endif
#ifndef NO_OF_SYMBOLS
#define NO_OF_SYMBOLS 1
#endif
namespace std{
class passwd{
char **pwd;
public:
passwd& operator=(const passwd);
passwd();
~passwd();
bool check_validity();
void tochar(char **);
void get();
};
}
上述头文件的函数:passwd.c++
#include<iostream>
#include"passwd.h"
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
using namespace std;
passwd::passwd()
{
pwd=(char **)malloc(sizeof(char*));
pwd[0]=(char *)malloc(9);
strcpy(pwd[0],"password");
}
passwd::~passwd()
{
free(pwd[0]);
free(pwd);
}
passwd& passwd::operator=(const passwd pswd)
{
pwd[0]=(char *)realloc(pwd[0],strlen(*pswd.pwd)+1);
strcpy(pwd[0],*pswd.pwd);
return *this;
}
bool passwd::check_validity()
{
if(strlen(pwd[0])<=MAX_PASSWD_LEN&&strlen(pwd[0])>=MIN_PASSWD_LEN);
else
return false;
int number_count=0,alphabet_count=0,symbol_count=0;
for(int i=0;i<strlen(pwd[0]);i++)
{
if(pwd[0][i]<='9'&&pwd[0][i]>='0')
{
number_count++;
}
else if((pwd[0][i]>='a'&&pwd[0][i]<='z')||(pwd[0][i]>='A'&&pwd[0][i]<='Z'))
{
alphabet_count++;
}
else if(pwd[0][i]>32&&pwd[0][i]!=127)
{
symbol_count++;
}
}
if(number_count>=NO_OF_NUMBERS&&alphabet_count>=NO_OF_ALPHABETS && symbol_count>=NO_OF_SYMBOLS)
return true;
else
return false;
}
void passwd::tochar(char **pswd)
{
*pswd=(char*)malloc(strlen(pwd[0])+1);
strcpy(*pswd,pwd[0]);
}
void passwd::get()
{
char *pswd;
pswd=getpass("");
pwd[0]=(char *)realloc(pwd[0],strlen(pswd)+1);
strcpy(pwd[0],pswd);
}
主程序:P1.c++
#include"passwd.h"
#include<iostream>
#include<stdlib.h>
int main()
{
using namespace std;
passwd p;
cout<<"Enter password: ";
p.get();
if(p.check_validity())
cout<<"Valid pwd.n";
else
cout<<"Invalid pwd.n";
char *s;
p.tochar(&s);
cout<<s<<endl;
passwd x=p;
free(s);
x.tochar(&s);
cout<<s<<endl;
free(s);
}
passwd 类有一个隐式定义的复制构造函数。如果您没有显式创建看起来有点像的构造函数
passwd(const passwd &other)
然后编译器自动生成一个,它只是复制所有成员。所以当你这样做时
passwd x=p;
然后你有效地做x.pwd = p.pwd;
.因此,当第二个passwd
被破坏时,您可以释放pwd[0]
并第二次pwd
。
要解决此问题,请显式定义一个复制构造函数,该构造函数执行您希望它执行的操作(可能分配一个新pwd
,然后将密码复制到其中pwd[0]
)。或者,或者,定义私有副本构造函数以防止它被使用。或者,如果您使用的是新式构造函数,则可以显式删除类声明中带有passwd(const passwd &other) = delete;
的复制构造函数。请注意,后两个选项将passwd x = p;
错误。
即使您由于另一个问题而passwd x; x = p;
,这也会中断:您的operator=
不引用原始文件,因此在调用它时会制作副本。通常人们会定义一个operator=(const passwd &pswd)
- 通过省略&
必须创建参数的副本,这是使用复制构造函数完成的,然后在您从operator=
返回后导致双重释放并且复制的pswd
被销毁。
相关文章:
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 无法访问嵌套类.类的使用无效
- 运算符C++ "delete []"仅删除 2 个前值
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 错误:从"int"到枚举c++的转换无效
- 如何修复此错误:className::className的无效使用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- C++-模板嵌套类的引用初始化无效
- g++用户定义的动态链接库上的全局new和delete运算符
- 错误:无效的预处理指令 #i 的意思是 #if?
- 多维数组 C++ 中数组下标的类型"int[int]"无效
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 在析构函数中使用 delete[]:为 RtlValidateHeap 指定的地址无效
- 使用delete防止C 14中使用无效的值呼叫
- 无效的free() / delete / delete[] / realloc(), 4 字节在大小为 16 的块内分配
- 在函数中使用delete[]:为RtlValidateHeap指定的地址无效
- 赋值运算符中的 free() / delete / delete[] / realloc() 错误无效