0
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define attr_size 3

int main(){
const char* attr[attr_size];
int i=0;
for(i=0;i<attr_size;i++){

    char* t=(char*)malloc(sizeof(int));
    sprintf(t,"%d",i);
    string temp="attr";
    temp+=t;
    attr[i]=temp.c_str();
    cout<<attr[i]<<endl;
    free(t);
}
for(i=0;i<attr_size;i++){
    cout<<attr[i]<<endl;
}
}

結果は次のとおりです。

attr0
attr1
attr2
attr2
attr
attr2

実際には、次の結果を得たいと考えています。

attr0
attr1
attr2
attr0
attr1
attr2

たぶんループに何か問題があります。誰か助けて?

4

1 に答える 1

3

問題は、c_str一時的なポインターを返すことです。したがって、ループが繰り返されると、ポインターを取得したオブジェクトが破棄され、ポインターが無効になり、後でそのポインターを逆参照したときに未定義の動作が発生します。

文字列の配列が必要な場合は、文字列の配列として宣言してみませんか?


コードには他にも問題があります。たとえば、12 文字 (符号と文字列ターミネータを含む) の文字列に 4 バイトしか割り当てないなどです。


次のようにプログラムを作り直すことをお勧めします。

#include <iostream>
#include <array>
#include <sstream>

const size_t ATTR_SIZE = 3;

int main()
{
    std::array<std::string, ATTR_SIZE> attr;

    for (int i = 0; i < ATTR_SIZE; ++i)
    {
        std::istringstream is;
        is << "attr" << i;
        attr[i] = is.str();
    }

    for (const std::string& s : attr)
        std::cout << s << '\n';
}

上記では、 (代わりにstd::array使用できますstd::vector) や範囲ベースforループ(代わりに通常の反復を使用できます) などの C++11 機能を使用しています。

于 2013-09-26T03:32:26.420 に答える