簡體   English   中英

C ++無法刪除char *,不斷破壞堆

[英]C++ can't delete char*, keeps corrupting heap

語言:C ++,編譯器:MSVS(/ Za)和g ++(是的,必須同時運行),級別:初學者

我試圖從char *中刪除數據,以便重新分配它並繼續執行程序。 我創建了一個新的char *,為其分配了命令行參數的值,進行了一些驗證,然后,如果驗證失敗,則應取消分配char *,然后讓我將新數據分配給var,但是我得到了“堆” Visual Studio中檢測到損壞”錯誤。 我對當前代碼的修復以及可以更清楚/簡潔地完成此操作的任何其他方式感到好奇。

在main()中:

//...
//make non constant versions to be messed with
char* ba = new char[ strlen(argv[4]) + 1 ];
char* num = new char[ strlen(argv[2]) + 1 ];

//make non constant versions of commandline stuff
nonConstant( argv[4], argv[2], ba, num );

//do the conversion and printing
convert( ba, num );
//...

轉換執行此操作:

//...
if( error ) {
    getNew(ba, num, &error);
}
//...

這是getNew:

void getNew( char* ba, char* num, bool error ) {

//if there's an error in their numbers let them input new stuff and check to see if that's valid
while( error ) {
    //tell the user that the input was bad an prompt for more, use getline because strings are weird
    //cin stuff here (this part works, no problems)

    //free up base and num so I can reassign them
    delete[] ba; //<--this line fails
    delete[] num;

    //set lengths = to lengths of input + 1 for \0
    ba = new char[ inputBa.length() + 1 ];
    num = new char[ inputNum.length() + 1 ];

    //do the assignment of new input back to base and num
    inputBa.copy( ba, inputBa.length(), 0 );
    inputNum.copy( num, inputNum.length(), 0 );

    //ensure that the input was good this time
    validateInput( ba, num, error );
}

立即切換到std::string

這將修復您的代碼,並根據要求使其更加清晰/簡潔。

如果您的getNew函數可以重新分配本地banum所指向的內存,即再次delete[]new[]進行分配。

但是,在convert中,調用banum呢? 另外, main banum呢? 它們按值傳遞給getNew ,這意味着它們保持不變。 它們繼續指向其原始(現已失效)的存儲位置。 我猜想您會繼續在convertmain使用那些現在毫無意義的banum值,直到它們導致崩潰。 例如,如果您getNew使用這些舊指針值調用getNew ,則getNew可能會在delete[]失敗。

同樣,還不能立即知道convert什么error getNew實際上需要一個bool參數時,為什么將它作為&error (可能是一個指針) getNew呢? 它將編譯,但無論如何看起來還是一個問題。

通過char *&傳遞參數將解決此問題。

#include <stdio.h>
#include <string.h>

void reassgnReference( char * &ba, char * &num );
void reassgnPointerToPointer( char ** ba, char ** num );

int main( int argc, char ** argv )
{
    if ( argc > 4 )
    {
        char * ba = new char[strlen( argv[ 4 ] ) + 1];
        char * num = new char[strlen( argv[ 2 ] ) + 1];

        strncpy( ba, argv[ 4 ], strlen( argv[ 4 ] ) );
        strncpy( num, argv[ 2 ], strlen( argv[ 2 ] ) );

        printf( "In the beginning, ba = %s, num = %s\n", ba, num );

        reassgnReference( ba, num );
        printf( "reassgnReference(), ba = %s, num = %s\n", ba, num );

        reassgnPointerToPointer( &ba, &num );
        printf( "reassgnPointerToPointer(), ba = %s, num = %s\n", ba, num );
}
else
{
    printf( "%s Expects at least 4 arguments\n", argv[ 0 ] );
}

return( 0 );
}

void reassgnReference( char *& ba, char *& num )
{
    delete[] ba;
    delete[] num;

    char const * const newBa = "ba from reference";
    char const * const newNum = "num from reference";

    ba = new char[strlen( newBa ) + 1];
    num = new char[strlen( newNum ) + 1];

    strncpy( ba, newBa, strlen( newBa ) );
    strncpy( num, newNum, strlen( newNum ) );
}

void reassgnPointerToPointer( char ** ba, char ** num )
{ 
    delete[] *ba;
    delete[] *num;

    char const * const newBa = "ba from pointer to pointer";
    char const * const newNum = "num from pointer to pointer";

    *ba = new char[strlen( newBa ) + 1];
    *num = new char[strlen( newNum ) + 1];

    strncpy( *ba, newBa, strlen( newBa ) );
    strncpy( *num, newNum, strlen( newNum ) );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM