当动态c字符串'textString'被类成员函数显示时,导致分段错误11。
#include "Text.h"
#include <iostream>
#include <cstring>
using namespace std;
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
char* textString = new char[textLength];
strcpy(textString, textArray);
cout << textString << endl;
}
Text::~Text()
{
delete[] textString;
}
void Text::displayText() const
{
cout << textString << endl;
}
我提供的驱动程序:
#include <iostream>
#include "Text.h"
using namespace std;
int main()
{
Text *myString1;
char tvshow[1000];
cout << "\n\nWhat is the most recent TV show you watched?\n";
cin.getline(tvshow, 1000);
myString1 = new Text(tvshow);
cout << "\n\nTV SHOW:\t";
myString1->displayText();
cout << "\t# CHARACTERS:\t" << myString1->getLength() << endl;
return 0;
}
在Text类的构造方法中,行
cout << textString << endl;
按预期工作。但是,当主函数调用myString1->displayText();
时,bash会以分段错误结束程序:11。任何帮助将不胜感激。谢谢。
最佳答案
除了what Algirdas says之外,您的另一个问题是,您实际上没有分配类成员textString
(假设您有一个成员),而是将其隐藏在构造函数中。
将构造函数更改为以下形式:
Text::Text(const char* textArray)
{
textLength = strlen(textArray);
textString = new char[textLength + 1];
strcpy(textString, textArray);
cout << textString << endl;
}
注意textString前面缺少的
char *
。我是怎么发现的?
与其他任何段错误一样,您应该学习如何调试。最好的工具是
gdb
和valgrind
。用valgrind运行它可以给我:$ echo franz | valgrind ./a.out
==6222== Memcheck, a memory error detector
==6222== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6222== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6222== Command: ./a.out
==6222==
What is the most recent TV show you watched?
franz
TV SHOW: ==6222== Invalid read of size 1
==6222== at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6222== by 0x108DB6: Text::getLength() const (a.cpp:37)
==6222== by 0x108E70: main (a.cpp:51)
==6222== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6222==
==6222==
==6222== Process terminating with default action of signal 11 (SIGSEGV)
==6222== Access not within mapped region at address 0x0
==6222== at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6222== by 0x108DB6: Text::getLength() const (a.cpp:37)
==6222== by 0x108E70: main (a.cpp:51)
==6222== If you believe this happened as a result of a stack
==6222== overflow in your program's main thread (unlikely but
==6222== possible), you can try to increase the size of the
==6222== main thread stack using the --main-stacksize= flag.
==6222== The main thread stack size used in this run was 8388608.
==6222==
==6222== HEAP SUMMARY:
==6222== in use at exit: 14 bytes in 2 blocks
==6222== total heap usage: 5 allocs, 3 frees, 77,838 bytes allocated
==6222==
==6222== LEAK SUMMARY:
==6222== definitely lost: 6 bytes in 1 blocks
==6222== indirectly lost: 0 bytes in 0 blocks
==6222== possibly lost: 0 bytes in 0 blocks
==6222== still reachable: 8 bytes in 1 blocks
==6222== suppressed: 0 bytes in 0 blocks
==6222== Rerun with --leak-check=full to see details of leaked memory
==6222==
==6222== For counts of detected and suppressed errors, rerun with: -v
==6222== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
fish: Process 6222, “valgrind” “echo franz | valgrind ./a.out” terminated by signal SIGSEGV (Address boundary error)
您可以清楚地看到,崩溃发生在
getLength
中,因为它试图访问地址0x0。当使用gdb运行它时,您将恰好在该位置停止并看到print textString
,它为0,并且未正确初始化。请阅读What is a debugger and how can it help me diagnose problems?以获取更多信息!