繁体   English   中英

从类成员函数访问字符串数组

[英]Accessing string array from class member function

我正在使用基本类,并尝试访问成员函数中的成员字符串数组。 我很困惑,因为如果我只调用set_wordsprint_wordsdel_words函数,则字符串数组将初始化并释放而没有任何内存错误(Dr. Memory):

class XWORD {
  public:
    int vdir;
    int len;
    int wid;
    int nWords;
    char ** arr;
    char ** words;     
    ...
};

void XWORD::set_words(int istart, int inWords, char* iwords[]) {
    int w = istart;
    int k = 0;
    this->nWords = inWords;

    this->words = new char* [this->nWords];
    for (w=istart; w<(istart+this->nWords); w++) {
        this->words[k] = new char [1+strlen(iwords[w])];
        this->words[k] = strcpy(this->words[k], iwords[w]);
        k++;
    }
}

void XWORD::del_words() {
    int w = 0;
    for (w=0; w<(this->nWords); w++) {
        delete[] this->words[w];
    }
    delete[] this->words;
}

void XWORD::print_words() {
    int w = 0;
    for (w=0; w<(this->nWords); w++) {
        printf("\n%s",this->words[w]);
    }
    printf("\n");
}

但是,当我调用以下函数时,出现如下所示的Dr.内存错误(单独的init_arrdel_arr也不提供错误):

void XWORD::add_word_to_arr(int iw, int iy, int ix) {
    int k = 0;
    int y = iy;
    int x = ix;

    for (k=0; k<(int)strlen(this->words[iw]); k++) {
        this->arr[y][x] = this->words[iw][k];
        if (this->vdir) {
            y++;
        } else {
            x++;
        }
    }
}

int main(int argc, char * argv[]) {
    XWORD x;
    x.set_words(1, argc-1, argv);
    x.init_arr(10,10);

    x.add_word_to_arr(0, x.len/2, x.wid/2); // WITHOUT THIS, NO ERRORS
    x.print_words();

    x.del_words();
    x.del_arr();
}

Dr. Memory Errors:

c:\MinGW\WORKSPACE\cpp\xword>make runmem
drmemory -brief -batch bin/test.exe
~~Dr.M~~ Dr. Memory version 1.8.0
~~Dr.M~~ Running "bin/test.exe"
~~Dr.M~~
~~Dr.M~~ Error #1: UNADDRESSABLE ACCESS beyond heap bounds: reading 4 byte(s)
~~Dr.M~~ # 0 XWORD::add_word_to_arr               [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:301]
~~Dr.M~~ # 1 main                                 [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:302]
~~Dr.M~~ Note: refers to 0 byte(s) beyond last valid byte in prior malloc
~~Dr.M~~
~~Dr.M~~ Error #2: UNADDRESSABLE ACCESS: reading 1 byte(s)
~~Dr.M~~ # 0 replace_strlen                       [d:\drmemory_package\drmemory\replace.c:375]
~~Dr.M~~ # 1 XWORD::add_word_to_arr               [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:301]
~~Dr.M~~ # 2 main                                 [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:302]
~~Dr.M~~
~~Dr.M~~ Error #3: LEAK 0 bytes
~~Dr.M~~ # 0 replace_operator_new_array               [d:\drmemory_package\common\alloc_replace.c:2638]
~~Dr.M~~ # 1 XWORD::set_words                         [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:301]
~~Dr.M~~ # 2 main                                     [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:302]
~~Dr.M~~
~~Dr.M~~ Error #4: LEAK 40 direct bytes + 110 indirect bytes
~~Dr.M~~ # 0 replace_operator_new_array               [d:\drmemory_package\common\alloc_replace.c:2638]
~~Dr.M~~ # 1 XWORD::init_arr                          [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:301]
~~Dr.M~~ # 2 main                                     [../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/crt1.c:302]
~~Dr.M~~
~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~       2 unique,     2 total unaddressable access(es)
~~Dr.M~~       0 unique,     0 total uninitialized access(es)
~~Dr.M~~       0 unique,     0 total invalid heap argument(s)
~~Dr.M~~       0 unique,     0 total GDI usage error(s)
~~Dr.M~~       0 unique,     0 total handle leak(s)
~~Dr.M~~       0 unique,     0 total warning(s)
~~Dr.M~~       2 unique,     2 total,    150 byte(s) of leak(s)
~~Dr.M~~       0 unique,     0 total,      0 byte(s) of possible leak(s)
~~Dr.M~~ Details: C:\Users\jesse\AppData\Roaming\Dr. Memory\DrMemory-test.exe.4512.000\results.txt
~~Dr.M~~ WARNING: application exited with abnormal code 0xc0000005
make: *** [runmem] Error 5

另外,当我在add_word_to_arr函数中打印this->words[0]的“%s”时,它为null 但是可以从print_words();打印出来print_words();

exe调用为:

bin\test.exe a123 b123

init_arr()是:

void XWORD::init_arr(int ilen, int iwid) {
    int y = 0;
    int x = 0;
    this->len = ilen;
    this->wid = iwid;

    this->arr = new char* [this->len];
    for (y=0; y<(this->len); y++) {
        this->arr[y] = new char [1+this->wid];
        for (x=0; x<(this->wid); x++) {
            this->arr[y][x] = BLANK;
        }
        this->arr[y][x] = (char) NULL;
    }
}

Ok init_arr(10,10)初始化一个由10个char数组组成的数组,大小为11(10个字符+ 1终止为null)。

然后,调用add_word_to_arr(0, 5, 5)以便将第一个单词(命令行的第一个参数add_word_to_arr(0, 5, 5)复制到数组中从位置5,5开始的位置。 因此,如果该单词是vdir == 0的至少7个字符或vdir!= 0的6个字符,则将写入保留数组之后。 我可以使用参数“ foo”和“ bar”成功运行,但不能使用“ feefoobar”运行。

您应该计算最长单词的长度,并在对int_arr的调用中使用它

无论如何,看起来您在测试vdir值时无需在任何地方对其进行初始化。 这会导致不确定的行为,因为您不知道将遵循哪个分支(水平或垂直),并且您实际上应该add_word_to_arr这种方式重写add_word_to_arr

void XWORD::add_word_to_arr(int iw, int iy, int ix) {
    int k = 0;
    int y = iy;
    int x = ix;

    for (k=0; k<(int)strlen(this->words[iw]); k++) {
        this->arr[y][x] = this->words[iw][k];
        if (this->vdir) {
            if (++y >= this.len) return; // refuse to write past allocated mem
        } else {
            if (++x > this.wid) return; // refuse to write past allocated mem
        }
    }
}

将vdir值一次强制设置为0,并将vdir强制设置为1 之后,却在调试器中执行了该命令,并且从未访问过分配的内存。 但是我不得不想象一些代码,因为您没有给出最小可编译的可验证示例

原来我正在从我的makefile运行我的make runmem工具,却忘了在我的make runmem目标中包含$(ARGS)

FLAGS = -Wall -std=c++11 -pedantic
LIBS = -Iinclude
SRC = src/xword.cpp
TGT = bin/test.exe
ARGS = human prothean vorcha krogan asari salarian turian batarian quarian

all:
    g++ $(SRC) -o $(TGT) $(FLAGS) $(LIBS)

run:
    $(TGT) $(ARGS)

runmem:
    drmemory -batch $(TGT) **$(ARGS)** # was missing

这就是为什么在Dr.Memory封装的执行过程中argv为空,以及为什么代码只会在这些过程中崩溃的原因。

$(ARGS)添加到此处的makefile ,没有崩溃,也没有报告错误/泄漏。

很抱歉追逐鹅,感谢您的帮助- 请让我知道这是否是应删除的多余职位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM