为什么我的数组元素检索函数返回随机值?

时间:2015-04-07 19:14:37

标签: c++ arrays string

我试图在C ++中创建一个自己的简单字符串实现。我的实现不是\0分隔的,而是使用我的字符数组中的第一个元素(我选择实现字符串的数据结构)作为字符串的长度。

本质上,我将此作为我的数据结构:typedef char * arrayString;并且我将以下内容作为一些原始字符串操作例程的实现:

#include "stdafx.h"

#include <iostream>

#include "new_string.h"

// Our string implementation will store the
// length of the string in the first byte of
// the string.
int getLength(const arrayString &s1) {
    return s1[0] - '0';
}

void append_str(arrayString &s, char c) {
    int length = getLength(s);              // get the length of our current string
    length++;                               // account for the new character
    arrayString newString = new char[length]; // create a new heap allocated string
    newString[0] = length;
    // fill the string with the old contents
    for (int counter = 1; counter < length; counter++) {
        newString[counter] = s[counter];
    }
    // append the new character
    newString[length - 1] = c;

    delete[] s;                             // prevent a memory leak
    s = newString;
}

void display(const arrayString &s1) {
    int max = getLength(s1);
    for (int counter = 1; counter <= max; counter++) {
        std::cout << s1[counter];
    }
}

void appendTest() {
    arrayString a = new char[5];
    a[0] = '5'; a[1] = 'f'; a[2] = 'o'; a[3] = 't'; a[4] = 'i';
    append_str(a, 's');
    display(a);
}

我的问题是我的函数getLength()的实现。我试图在Visual Studio中调试我的程序,一开始看起来都很好。

第一次调用getLength()时,在append_str()函数内,它返回字符串长度(5)的正确值。当它在display()内被调用时,我自己的自定义字符串显示函数(以防止std::cout的错误),它正确读取值(6),但返回的 -42 ?发生了什么事?

enter image description here

备注

  1. 忽略我在代码中的评论。它纯粹是教育性的,只是我试图看看哪种级别的评论改进了代码以及什么级别降低了它的质量。
  2. get_length()中,我必须执行first_element - '0',否则,该函数将返回算术值的ascii值。例如,对于十进制6,它返回54
  3. 这是一项教育活动,所以如果你看到任何其他值得评论或修理的事情,请告诉我。

4 个答案:

答案 0 :(得分:3)

由于您在[{1}}中获得return s1[0] - '0';的长度,因此您应将长度设置为getLength()而不是newString[0] = length + '0';

作为一个方面,为什么要在数组中存储字符串的大小?为什么没有你存储大小的某种整数成员。几个字节真的不会受到伤害,现在你有一个字符串,可以超过256个字符。

答案 1 :(得分:2)

您正在几个地方访问您的阵列。

append_str

for (int counter = 1; counter < length; counter++) {
    newString[counter] = s[counter];
}

在您提供的示例中,起始字符串为“5foti” - 没有终止空字符。最大有效索引为4。在上述功能中,length已设置为6,您正在访问s[5]

可以通过将for语句中的条件更改为counter < length-1;

来解决此问题

display

int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
    std::cout << s1[counter];
}

在这里,您再次使用循环中的counter <= max来访问数组。

可以通过将for语句中的条件更改为counter < max;

来解决此问题

答案 2 :(得分:1)

以下是一些改进,也应该涵盖您的问题:

  1. 而不是typedef,为您的字符串定义一个类。该类的长度应为int,字符串数据本身应为char*
  2. 在您的班级中使用运算符重载&#34; string&#34;所以你可以用+等附加它们
  3. - '0'给了我痛苦。从长度中减去ASCII值42,但不要将其作为字符添加。此外,长度最多可以为127,因为char从-128到+127。见第1点。
  4. append_str更改对象的指针。这是非常糟糕的做法!

答案 3 :(得分:1)

好的,谢谢大家的帮助。

问题似乎出现在appendTest()函数中,我在数组的第一个元素中存储了我想要的值作为大小的字符代码(即存储'5'而不是只是5)。我似乎没有编辑我之前正确的代码,这就是导致我出现这些问题的原因。

除了你们许多人所要求的为什么我不使用课程或更好的设计,因为我想实现一个基本的字符串结构有很多约束,比如没有类等。我基本上只想使用数组,而我自己提供的最多就是动态分配它们,即可调整大小。