为什么我在尝试将字符传递给我的函数以及如何修复它时会获得 SIGSEGV
Why do I get SIGSEGV when trying to pass a char to my function and how to fix it?
我在类中重载了operator=
,我需要确定我的字符串是否包含数字。 不幸的是,我需要主要使用 C 数组 ( char*
(,原因有两个:
- 训练
-
使用 std::string 将需要我更改 100+ 行代码。
当尝试将值从
char*
数组传递给我的函数时,我得到了一个非常好的 SEGFAULT,不幸的是我不确定为什么。可能我没有正确使用我的指针。
我搜索了几个小时,但我无法找到这个问题的解决方案。无论如何,这是代码。如果您需要有关此事的更多信息,请在评论中告诉我。
#include <limits.h>
#include <iostream>
#include <string.h>
#include <exception>
struct notdig : public std::exception {
virtual const char* what() const throw() override{
return "int_huge: isdig(*(o + i)) returned false. nYour declaration of an int_huge integer should contain decimal digits.";
}
};
class int_huge {
private:
char* buffera;
char* bufferb;
int numDig(unsigned long long int number){ //Gets the number of digits
int i = 0;
while(number){
number /= 10;
i++;
}
return i;
}
inline bool isdig( char character ) { //Checks whether character is digit or not
return ( '0' <= character && character <= '9' );
}
public:
int_huge(){
this->buffera = "0";
this->bufferb = "0";
}
void operator=(char* operand){
for (int i = 0; i < strlen(operand); i++){
if (!isdig(operand[i])){
throw notdig();
}
}
if (strlen(operand) >= numDig(ULLONG_MAX)){
if (strlen(operand) - numDig(ULLONG_MAX)){ //Equivalent with if (strlen(operand) != numDig(ULLONG_MAX)
int i = 0;
while (i < strlen(operand)-numDig(ULLONG_MAX)){
this->buffera[i] = operand[i];
i++;
}
this->bufferb = operand + i;
} else {
this->buffera[0] = operand[0];
this->bufferb = operand + 1;
}
} else {
this->buffera = "0";
this->bufferb = operand;
}
}
};
int main() {
int_huge object;
try {
object = "90";
} catch (std::exception &e) {
std::cout << e.what();
}
}
反汇编器结果:
0x4019b4 push %ebp
0x4019b5 mov %esp,%ebp
0x4019b7 push %ebx
0x4019b8 sub $0x24,%esp
0x4019bb mov 0xc(%ebp),%eax
0x4019be mov %eax,(%esp)
0x4019c1 call 0x401350 <strlen>
0x4019c6 mov %eax,%ebx
0x4019c8 movl $0xffffffff,0x4(%esp)
0x4019d0 movl $0xffffffff,0x8(%esp)
0x4019d8 mov 0x8(%ebp),%eax
0x4019db mov %eax,(%esp)
0x4019de call 0x40195c <int_huge::numDig(unsigned long long)>
0x4019e3 cmp %eax,%ebx
0x4019e5 setae %al
0x4019e8 test %al,%al
0x4019ea je 0x401aa8 <int_huge::int_huge(char*)+244>
0x4019f0 mov 0xc(%ebp),%eax
0x4019f3 mov %eax,(%esp)
0x4019f6 call 0x401350 <strlen>
0x4019fb mov %eax,%ebx
0x4019fd movl $0xffffffff,0x4(%esp)
0x401a05 movl $0xffffffff,0x8(%esp)
0x401a0d mov 0x8(%ebp),%eax
0x401a10 mov %eax,(%esp)
0x401a13 call 0x40195c <int_huge::numDig(unsigned long long)>
0x401a18 cmp %eax,%ebx
0x401a1a setne %al
0x401a1d test %al,%al
0x401a1f je 0x401a8d <int_huge::int_huge(char*)+217>
0x401a21 movl $0x0,-0xc(%ebp)
0x401a28 mov 0xc(%ebp),%eax
0x401a2b mov %eax,(%esp)
0x401a2e call 0x401350 <strlen>
0x401a33 mov %eax,%ebx
0x401a35 movl $0xffffffff,0x4(%esp)
0x401a3d movl $0xffffffff,0x8(%esp)
0x401a45 mov 0x8(%ebp),%eax
0x401a48 mov %eax,(%esp)
0x401a4b call 0x40195c <int_huge::numDig(unsigned long long)>
0x401a50 sub %eax,%ebx
0x401a52 mov %ebx,%edx
0x401a54 mov -0xc(%ebp),%eax
0x401a57 cmp %eax,%edx
0x401a59 seta %al
0x401a5c test %al,%al
0x401a5e je 0x401a7d <int_huge::int_huge(char*)+201>
0x401a60 mov 0x8(%ebp),%eax
0x401a63 mov (%eax),%edx
0x401a65 mov -0xc(%ebp),%eax
0x401a68 add %eax,%edx
0x401a6a mov -0xc(%ebp),%ecx
0x401a6d mov 0xc(%ebp),%eax
0x401a70 add %ecx,%eax
0x401a72 movzbl (%eax),%eax
0x401a75 mov %al,(%edx) ;This is where the compiler stops. Probably due to SIGSEGV.
0x401a77 addl $0x1,-0xc(%ebp)
0x401a7b jmp 0x401a28 <int_huge::int_huge(char*)+116>
0x401a7d mov -0xc(%ebp),%edx
0x401a80 mov 0xc(%ebp),%eax
0x401a83 add %eax,%edx
0x401a85 mov 0x8(%ebp),%eax
0x401a88 mov %edx,0x4(%eax)
0x401a8b jmp 0x401aba <int_huge::int_huge(char*)+262>
0x401a8d mov 0x8(%ebp),%eax
0x401a90 mov (%eax),%eax
0x401a92 mov 0xc(%ebp),%edx
0x401a95 movzbl (%edx),%edx
0x401a98 mov %dl,(%eax)
0x401a9a mov 0xc(%ebp),%eax
0x401a9d lea 0x1(%eax),%edx
0x401aa0 mov 0x8(%ebp),%eax
0x401aa3 mov %edx,0x4(%eax)
0x401aa6 jmp 0x401aba <int_huge::int_huge(char*)+262>
0x401aa8 mov 0x8(%ebp),%eax
0x401aab movl $0x4030d2,(%eax)
0x401ab1 mov 0x8(%ebp),%eax
0x401ab4 mov 0xc(%ebp),%edx
0x401ab7 mov %edx,0x4(%eax)
0x401aba nop
0x401abb add $0x24,%esp
0x401abe pop %ebx
0x401abf pop %ebp
0x401ac0 ret
in
MyClass(){
this->a = "0";
this->b = "0";
}
并在main
o = "90";
字符串文本(可能不在可写存储中(分配给指向 char
的非常量指针。编译器应该警告您这一点,或者如果编译器支持 C++11 或更高版本的标准,则直接拒绝编译。
这爆炸的地方在这里operator=
:
this->a[i] = o[i];
在这里:
this->a[0] = o[0];
当程序尝试写入无法写入的存储时。
溶液:
使用 std::string
.如果这不在桌面上,并且听起来确实如此,请不要使用字符串文字。使用 new
在可写内存中分配缓冲区,将文本复制到缓冲区中,然后分配缓冲区。还要记住,缓冲区的大小是固定的。尝试在缓冲区中放置较大的字符串将导致灾难。
这将是一个令人头疼的记忆管理问题,也是一个潜在的三法则恐怖节目,所以要小心。
相关文章:
- 静态数据成员的问题-修复链接错误会导致编译器错误
- Boost Graph Library,修复节点大小
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 如何修复函数样式强制转换或类型构造的预期"("?
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 当使用带有VS2019或VSCode的虚幻引擎4.24.2时,我如何修复这些错误的Intellisense错误
- 如何修复sfml c++代码编译错误
- Python中的for循环与C++有何不同
- 如何修复此iFile以将.txt输出到控制台
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 如何修复此错误:className::className的无效使用
- 叮叮当当在修复时插入多个"覆盖"说明符
- 如何修复带有 clang 的参数'args'缺少默认参数的问题?
- 哪个部分导致"SIGSEGV"错误以及如何修复它?
- 为什么我在尝试将字符传递给我的函数以及如何修复它时会获得 SIGSEGV
- Qt opengl调试SIGSEGV如何修复
- 分段故障错误(信号名称:SIGSEGV)的原因是什么,以及如何查找/修复它