坏指针?- C++

3
我正在用C++编写一个使用指针的字符串标记化程序,作为一项家庭作业。然而,当我运行和调试它时,它显示我的指针pStart无效。我觉得我的问题在于我的参数化构造函数,下面包括了构造函数和对象创建的代码。
希望您能告诉我为什么在调试时它说pStart是一个坏指针。
谢谢!
StringTokenizer::StringTokenizer(char* pArray, char d)
{
pStart = pArray;
delim = d;
}

// create a tokenizer object, pass in the char array
// and a space character for the delimiter
StringTokenizer tk( "A test char array", ' ' );

完整的stringtokenizer.cpp文件:

#include "stringtokenizer.h"
#include <iostream>
using namespace std;

StringTokenizer::StringTokenizer(void)
{
pStart = NULL;
delim = 'n';
}

StringTokenizer::StringTokenizer(const char* pArray, char d)
{
pStart = pArray;
delim = d;
}

char* StringTokenizer::Next(void)
{
char* pNextWord = NULL;

while (pStart != NULL)
{
    if (*pStart == delim)
    {
        *pStart = '\0';
        pStart++;
        pNextWord = pStart;

        return pNextWord;
    }
    else
    {
        pStart++;
    }
}
    return pNextWord;
}

函数Next应该返回一个指向字符数组中下一个单词的指针。目前它还没有完成。 :)

完整的stringtokenizer.h文件:

#pragma once

class StringTokenizer
{
public:
StringTokenizer(void);
StringTokenizer(const char*, char);
char* Next(void);
~StringTokenizer(void);
private:
char* pStart;
char delim;
};

完整的main.cpp代码:

const int CHAR_ARRAY_CAPACITY = 128;
const int CHAR_ARRAY_CAPCITY_MINUS_ONE = 127;

// create a place to hold the user's input
// and a char pointer to use with the next( ) function
char words[CHAR_ARRAY_CAPACITY];
char* nextWord;

cout << "\nString Tokenizer Project";
cout << "\nyour name\n\n";
cout << "Enter in a short string of words:";
cin.getline ( words, CHAR_ARRAY_CAPCITY_MINUS_ONE );

// create a tokenizer object, pass in the char array
// and a space character for the delimiter
StringTokenizer tk( words, ' ' );

// this loop will display the tokens
while ( ( nextWord = tk.Next ( ) ) != NULL )
{
    cout << nextWord << endl;
}


system("PAUSE");
return 0;

你收到了什么错误信息? - ihtkwot
CXX0030:错误:无法评估表达式。 - Alex
CXX003不是C/C++运行时/编译时错误,而只是在调试器中显示的错误,说明您正在误用值评估器 - http://msdn.microsoft.com/en-us/library/360csw6a(VS.71).aspx。如果您能发送更完整的代码,则会更好。您粘贴的部分是不完整且形式不正确的,即pStart是什么? - mloskot
请发布实际的代码和实际的错误信息。编译时错误“表达式无法评估”与您报告的“在调试时pStart是一个错误指针”完全不同。 - user97370
4个回答

3

您无法在令牌化器中修改pStart,因为C和C ++中的文字字符串是不可修改的,它具有类型const char *。当您执行赋值操作时

pStart = pArray;

在你的构造函数中,pStart现在指向一个不可修改的内存。很可能这就是你的问题所在。如果不是这种情况,你需要发布更多的代码。
编辑:看了你的编辑后,似乎你已经改变了代码以使用数组。这很好。我没有详细查看你的代码,但至少有一个错误:
while (pStart != NULL)

should be:

while (pStart != NULL && *pStart)

这是因为当你在字符串中遇到终止符'\0'时,你希望停止循环。
我不确定你为什么在C++中使用C风格的字符串。这是你作业的要求吗?

如果我使用char数组,这会改变什么吗? - Alex
字符数组在哪里?如果pStart是一个字符数组,那么这个赋值甚至无法编译:在C++中你不能对数组进行赋值。请发布完整的最小代码。 - Alok Singhal

1

更改

StringTokenizer::StringTokenizer(char* pArray, char d)

StringTokenizer::StringTokenizer(const char * pArray, char d)

字符串字面值始终是一个const char * const变量,由于C++会自动将非const转换为const,因此它无法将const转换为非const。

您还可以创建不同的构造函数,但我认为只要您仅读取pArray字符串,就不需要它。

您可以使用类似以下的内容:

TokenList& StringTokenizer::StringTokenizer(const char* pArray, char d){
  TokenList lst();
  size_t i=0;
  char buffer[100]; //hardcoded limit, just an example, you should make it grow dinamically, or just use a std::string
  while((*pArray)){
    if(*pArray == d){
      buffer[i] = 0; //string ending character, 0 = '\0';
      lst.add(buffer);
      i=0;
    }
    pArray++;
  }
  //Last token in the input string won't be ended by the separator, but with a '\0'.
  buffer[i] = 0;
  lst.add(buffer);

  return lst;
}

但是现在我得到了这个错误:error C2440: '=' : 无法将类型为 'const char *' 的值赋给类型为 'char *' - Alex
请添加更多信息。你看,字符串字面值是常量,你不能以任何方式改变它。我认为你实际上是将它分配给另一个char,但你不能这样做,你必须将它分配给另一个const char。 我会编辑答案,向你展示一些实际的代码,因为我正在思考。 - Spidey

0
在我看来,你应该改变StringTokenizer的构造函数和析构函数:
StringTokenizer::StringTokenizer(char* pArray, char d)
{
    pStart = str = strdup( pArray );
    delim = d;
}

StringTokenizer::~StringTokenizer(char* pArray, char d)
{
    free( str );
}

现在您可以按照您使用的方式使用pStart:修改字符串,放置零以标记单词等等。您只需要向StringTokenizer添加一个“char * str”私有属性即可。

关键在于您正在创建自己的字符串副本,因此可以按照任何您想要的方式操纵它,只要您在析构函数中释放它即可。唯一的缺点是您需要内存来存储副本(因此每个字符串需要两倍的内存)。

您的解决方案之所以不起作用是因为文字常量可能存储在只读内存中,因此它们被正确标记为const char*,因此无法写入。


0

将StringTokenizer类中的pStart从char*更改为const char*,并对构造函数进行相同的更改。


谢谢!你在项目中提供了重要的帮助! - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接