坏指针? - C ++

时间:2010-02-06 03:17:32

标签: c++ pointers tokenize arrays

我正在为C ++中的家庭作业编写一个字符串标记化程序,它使用指针。但是,当我跑步&调试它,它说我的指针pStart,无效。我感觉我的问题存在于我的param'ed构造函数中,我在下面包含了构造函数和对象创建。

如果您可以告诉我为什么在调试它时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用于返回指向char数组中下一个单词的指针。它目前尚未完成。 :)

完整的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;

4 个答案:

答案 0 :(得分:3)

您无法在tokenizer中修改pStart,因为C和C ++中的文字字符串不可修改,它的类型为const char *。当你完成作业

pStart = pArray;

在你的构造函数中,pStart现在指向一个不可修改的内存。最有可能的是你的问题。如果情况并非如此,您将需要发布更多代码。

编辑:查看编辑后,看起来您已更改代码以使用数组。非常好。我没有详细查看您的代码,但至少有一个错误:

while (pStart != NULL)

应该是:

while (pStart != NULL && *pStart)

这是因为当您点击字符串中的终止'\0'时,您想要停止循环。

我不确定你为什么在C ++中使用C风格的字符串。这是你作业的要求吗?

答案 1 :(得分: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;
}

答案 2 :(得分:0)

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

答案 3 :(得分: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 *,“不可能”写入它们。