9

こんにちは、次のテスト コードがあり、cpp について混乱しています。

  1. library.h で空の要素句を含む配列を宣言すると、コンパイラは何を選択しますか? それも文句はありません。私はCygwinを使用しています。

  2. library.cpp で 2 つの要素に値を割り当てます。コンパイラは 1 つの要素を持つ配列を想定し、配列の範囲外に 2 番目の要素を書き込みますか?

ライブラリ.h

#ifndef LIBRARY_H
#define LIBRARY_H

class library {

public:
    void print();
    char a[];
};

#endif

ライブラリ.cpp

#include <stdio.h>
#include "library.h"

void library::print() {
    a[0] = 'a';
    printf("1. element: %d\n", a[0]);
    a[1] = 'b';
    printf("2. element: %d\n", a[1]);
}

client.cpp

#include <stdio.h>
#include "library.h"

void execute();
library l;

int main() {
    l = library();
    l.print();
    return 0;
}

メイクファイル

OPTIONS=-Wall

all: main

run: main
        ./main.exe

main: client.o library.o
        g++ $(OPTIONS) -o main $^

library.o: library.cpp library.h
        g++ $(OPTIONS) -c $<

.cpp.o:
        g++ $(OPTIONS) -c $<

clean:
        rm -r *.o
4

4 に答える 4

11
  1. C/C++ と呼ばれる言語はないため、Q を両方でタグ付けすることはできません。
  2. クラスを使用しているため、プログラムは C ではなく C++ のみにすることができます。

public:
     void print();
     char a[];

このコードは、C++ では単純に違法です。C++ の配列サイズは、正のコンパイル時定数である必要があります。解決策は、次のように置き換えることです。

public:
      void print();
      std::string a;

宣言に注意してください。

char a[];

は c99 で有効であり、不完全な配列型aとして知られています。C 標準では、この型の要素を少なくとも 1 つ格納できることが保証されていますchar。これは C++ では無効です。C++ 標準では、これらは許可されていません。単純に、両者は異なる言語だからです。

于 2013-03-19T08:38:35.467 に答える
6

まず、それは合法的なC++ではありません。これは古いハックであり、CはC98でのみ合法化しました。基本的な考え方は、これはstruct(を使用して)動的にのみ割り当てることができmalloc、その後のオブジェクトに必要なメモリをいくらでも割り当てることができるということです。だからあなたはのようなことをするでしょうmalloc( sizeof( library ) + strlen( s ) + 1 )。ハックは、余分な割り当てを回避するために使用されます。

このハックを使用するクラスは、と一緒に使用することはできませんnew。また、メンバーまたは基本クラスにすることもできません。(Cのメンバーになることもできません。)

これはC++でエミュレートできます。

class Library
{
    //  ...
    char* buffer() { return reinterpret_cast<char*>( this + 1 );
    void* operator new( size_t n, size_t extra )
    {
        assert( n == sizeof( Library ) );
        return ::operator new( n + extra );
    }
};

ただし、Cソリューションとは異なり、これには位置合わせの問題が発生するリスクがあることに注意してください。これは文字タイプに対しては正常に機能し、クラスの他のメンバーが少なくともバッファータイプと同じ量の整列を必要とする場合は機能しますが、そうでない場合は失敗する可能性があります。(g++でのstd:: basic_stringの実装はそれを使用し、でインスタンス化された場合、一部のマシンでクラッシュしますdouble。)

于 2013-03-19T08:49:51.917 に答える
5

空の配列は長さ 0 の配列を宣言します。sizeof(S) よりも大きなメモリ ゾーンに構造体 S を配置し、配列を使用して残りのメモリにアクセスすることにより、C で使用されます。

memory* ptr = malloc(sizeof(memory) + sizeof(char) * 10);
// you can now manipulate ptr->a as an array of 10 elements

これは、C++ ではあまり役に立たないトリックです。代わりに std::vector を使用してください。

于 2013-03-19T08:31:14.350 に答える
1

これは、一般に Cの構造体ハックと呼ばれます。それは、柔軟な配列メンバーと呼ばれる機能を使用します。

ただし、これは C++ 標準仕様の一部ではありません。この質問を見てください。

何かが明らかに機能するという観察は、それが確実に機能することに依存できることを意味するものではないことに注意してください。動作が定義されていない場合、技術的には何でも発生する可能性があります。急襲する猛禽類も含めて。

C++ では、おそらく代わりにastd::vector<char>または aを使用するでしょう。std::string

于 2013-03-19T08:41:06.227 に答える