2017-06-24 10 views
0

中の未知の型の配列からポインタの配列を作成しとります私は機能のインクルードを記述する必要がC

未知のタイプの配列、要素

とポインタの配列を返すの配列や大きさのサイズを:最初は負の値、次に正の値です。

void *mix(void *A, int nElementsA, int sizeOfAnElement) { 
    char** res = (char**)malloc(sizeof(char*)*nElementsA*sizeOfAnElement); 
    char* p = (char *)A; 
    char* bStart = res[0]; 
    char* bEnd = res[nElementsA*sizeOfAnElement - sizeOfAnElement]; 
    while (p<(char*)A + nElementsA*sizeOfAnElement) { 
     if (*(int*)p>0) { 
      bStart = p; 
      bStart += sizeOfAnElement; 
     } 
     else { 
      bEnd = p; 
      bEnd -= sizeOfAnElement; 
     } 
     p += sizeOfAnElement; 
    } 
    return res; 
} 

を、私はゴミの完全な配列、間違っ 何のIV鳩を取得:これは、IVがこれまで行って何ですか?

+0

あなたは[MCVE]あなたが/呼び出しを使用する方法を示すことはできます関数? – Yunnosch

+1

何を解釈して処理したいのですか*あなたはそれが何であるかを知らない*?あなたはそれが "否定的要素"を持っていることさえ知ることさえできません。あなたは現在、すべてを 'int' *として解釈しています。 'int'配列を渡すこともできます。 – tofro

答えて

0

まず、あなたがしようとしていることは不可能でほとんど意味がありません。

an unknown type arrayあなたはではありません。は配列の要素にアクセスできません。こう:

(*(int*)p 

はあなたがタイプint(または互換)のように要素を想定していることを意味します。これは明らかにタイプが不明であることと矛盾します。そのほかに

....

このライン

malloc(sizeof(char*)*nElementsA*sizeOfAnElement); 

あまりにも多くのメモリを割り当てます。それだけで、各要素のポインターを割り当てるもの、すなわち

malloc(sizeof(char*)*nElementsA); 
0

修正:必要なものの

void *mix(void *A, int nElementsA, int sizeOfAnElement, 
      int (*isPositive)(const void *)) { 
    // Allocate a `char*` array containing `nElementsA` pointers. 
    char **res = malloc(nElementsA * sizeof *res); 

    // &p[i] == &A[i] 
    char (*p)[sizeOfAnElement] = A; 

    // bStart points to the first result element. 
    char **bStart = &res[0]; 

    // bEnd points to the last result element. 
    char **bEnd = &res[nElementsA - 1]; 

    // Loop through the array, 
    // adding &A[i] at the start of the result array if positive, 
    // else at the end of the result array. 
    for (int i = 0; i < nElementsA; i++) { 
     if (isPositive(p[i])) { 
      *bStart = p[i]; 
      bStart++; 
     } 
     else { 
      *bEnd = p[i]; 
      bEnd--; 
     } 
    } 
    return res; 
} 

あなたの理解が割り当てられることに、どのようにあなたのポインタが間違っていた使用方法。

ポインタの配列を作成する場合は、ポインタnElementsA * sizeOfAnElementではなくポインタnElementsAを割り当てる必要があります(ポインターを格納していますが、ポインタが指すオブジェクトのコピーではありません)。

bStartbEndを間違って作成して使用しました。 intオブジェクトの配列を移動する場合は、int*オブジェクトが必要です。 bStartbEndの場合、char*の配列を移動したいので、char**が必要です。

あなたはint以外の型を扱うことができますので、私は、関数ポインタのパラメータを追加しました(代わりにint *Avoid *AsizeOfAnElementを使用してのポイントは他に何が?)、あなたはそれで助けが必要な場合は、ここでの回答とチュートリアルの多くがありますあなたは検索エンジンで見つけることができます。

私はまた、pを配列のポインタに変更する自由を取ったので、コンパイラはあなた自身ではなくポインタの算術演算を実行できます。もしあなたが好きなら、それを元に戻すことができます。あなたは(つまり、あなたがiを使用することはできません)ループ内のポインタを使用したい場合は、ここでそれを行うループのバージョンです:

// I added the typedef for more easily understood declarations of `p` and `end`. 
typedef char array_alias_t[sizeOfAnElement]; 

// p's type is the same as in the previous code (char (*)[sizeOfAnElement]). 
array_alias_t *p = A; 

// p + x == &p[x], and &p[nElementsA] is one element past the end of A, 
// which is allowed by ISO C, provided you don't dereference the pointer 
// (i.e. *end is not allowed). 
for (array_alias_t *end = p + nElementsA; p != end; p++) { 
    if (isPositive(*p)) { 
     *bStart = *p; 
     bStart++; 
    } else { 
     *bEnd = *p; 
     bEnd--; 
    } 
} 
関連する問題