访问动态数组导致运行时错误

时间:2017-04-27 21:10:26

标签: c++ arrays memory dynamic

我一直在搞乱动态记忆,而且我已经撞到了一堵巨大的墙。

我正在尝试创建一个程序,用户可以根据需要输入任意数量的字符串,然后可以在任何时候退出,但是在输入第二个字符串后,程序会崩溃而不给我任何特定的错误消息。

#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "new"

int _tmain(int argc, _TCHAR* argv[])
{
    //Variables
    int i=0,end=0,requiresSize=1;
    char ** temp;
    char  item[256]="a";
    char ** requires;


    //Initialize each element in requiers
    requires = new char * [requiresSize];
    for(int j=0;j<requiresSize*2;j++){
        requires[j]= new char[256];
    }


    while(strcmp(item,"q-")){
        end=0;
        printf("Enter h- for help.\nEnter q- to quit.\n");
        printf("Please enter a string\n");
        gets_s(item);
        if(!strcmp(item,"h-")){
            printf("Enter a string to add to the list.\nEnter p- to print the list.\n");
            end=1;
        }   
        if(!strcmp(item,"q-")){
            break;
        }
        if(!strcmp(item,"p-")){
            if(requires[0]!=NULL){
                for(int j=0;j<requiresSize;j++){
                    printf("%d. %s\n",j,requires[j]);
                }
            }
            end=1;
        }
        while(end==0){
                printf("check1:i=%d\n",i);
            //if search index is larger than size of the array,reallocate the array
            if(i>= requiresSize){
                temp = new char * [requiresSize*2];
                //Initialize each element in temp
                printf("check2:temp initalized\n");
                for(int j=0;j<requiresSize*2;j++){
                    temp[j]= new char[256];
                }
                printf("check3:temp itmes initialized\n");
                for(int j =0;j<requiresSize;j++){
                    //for each element in requires, copy that element to temp
                    temp[j]=requires[j];
                }
                printf("check4:copied requires into temp\n");
                delete * requires;
                requires = temp;
                printf("check5:deleted requires and set requires equal to temp\n");
                delete  temp;
                requiresSize = requiresSize *2;         
            }
                printf("check6:\n");
            //if the index at requires is not empty, check to see if it is the same as given item
            if(requires[i]!= NULL){
                printf("check8:index at requires is not empty\n");
                //I know the error occurs here, something to do with accessing requires[i]
                if(!strcmp( item,  requires[i])){
                printf("check9:index at requires is the same as item\n");
                    //if they are the same, break out of the loop, item is already included
                    break;
                }else{
                printf("check10:index at requires is different\n");
                    //otherwise, increase the index and check again (continue loop)
                    i++;
                    break;
                }
            }else{
                printf("check11:index at requires is null, item added\n");
                //if the index is empty, add the item to the list and break out of loop
                requires[i]=  item;
                break;
            }
                printf("check7\n");

        }
    }
    delete requires;
    return 0;
}

提前谢谢。

1 个答案:

答案 0 :(得分:1)

你需要意识到一个赋值语句,例如temp = requires(在这种情况下)只是复制指针,所以temp现在指向内存中与{{1}相同的位置}};它不会复制那段记忆。

这导致了两个问题:

  1. 您正在为requires的每个元素分配新的256-char数组,然后在temp中重新分配每个char *以指向不同的位置,泄漏所有内存;现在无法引用新分配的内存,因此无法释放它。

  2. 您正在将指针temp分配给temp,这也就是说,这两个指针现在指向内存中的相同位置,然后删除requires,这释放了那个记忆(同样,temp现在也指向了这个记忆)。

  3. 此外,如果您使用requires分配数组,则必须使用new[]来释放它。因此delete[]要求您在程序结束时使用requires = new char * [requiresSize];,而不仅仅是delete [] requires;。对于delete requires;的每个256-char元素也是如此。

    因此,用适当的strcpy(或strncpy)调用替换requires。并且不要删除temp[j]=requires[j];;最后的temp将处理它,因为它现在指向那一点内存。