2012-03-21 1 views
1

EDIT:nvccがmalloc(3)をキャストしていないときにエラーが発生したためにCコンパイラの代わりにC++コンパイラを呼び出すため、 char *を呼び出します。私はこのアサーションに導かれています。Invalid converstion from void* to char**nvccを使用しているときに書き込み可能なファイルを開くことができません

EDITEDIT:fileO = fopen(version、 "w")を使用するとうまく動作します。 strcpyとstrcatの呼び出しをバイパスします。 (ハハ、私はcatcalls ...)

私は同じプログラム(非CUDA)のシーケンシャルバージョンからいくつかのファイルI/Oを収穫したCUDAプログラムがあります。まったく同じコードは、通常のgccコンパイルでは動作しますが、nvccでは動作しません。私は、ネイティブなC++コンパイラにnvccがC/C++をシャントすることを知っていますが、なんらかの理由で書き込み可能なファイルを開いていないだけです。上記のコードでデータを読み込むために別のファイルストリームを開いたり閉じたりしましたが、私はこれを私のシーケンシャルバージョンで行い、そこではうまくいきます。私は毎回「ファイルの作成に失敗した書き込み」を取得

else 
{ 
    char* version = "matrixExpCUDAx"; 
    char* filename = (char *)malloc(strlen(version) + strlen(argv[3])); 

    strcpy(filename, version); 
    strcat(filename, argv[3]); 

    FILE *fileO; 
    fileO = fopen(filename, "w"); 

    if(DEBUG) 
    { 
     for (i=0; i<(dim*dim); i++) fprintf(stderr, "%f\n", h_O[i]); 
    } 
    else 
    { 
     if(fileO != NULL) 
     { 
      for (i=0; i<(dim*dim); i++) 
      { 
       fprintf(fileO, "%f\n", h_O[i]); 
      } 
      fclose(fileO); 
     } 
     else fprintf(stderr, "Write file failed to create\n"); 
    } 
} 
.... 

はここに関連するコードです。

アイデア?

+0

トップの近くで失敗したコードの書式に注意してください。それを修正できますか? (他の人もそれを修正することができますが、同時に複数の人が投稿を編集しようとすると、誰かにとって迷惑になります..) – sarnold

+0

'nvcc'はコンパイラではなく、このコードをコンパイルしませんでした。あなたの標準的なホストC++コンパイラ(タグの外観による 'gcc')はそうでした。外見にもかかわらず、この質問はCUDAやCUDAツールチェーンとは関係がありません.Cの文字列終了については理解していません。 – talonmies

+0

@talonmies:ありがとうございます。私は、nvccが元の投稿でシステムCコンパイラを使用していることに注意しました。私はコードのCUDA固有の部分とコンパイラとしてのgccなしで動作するので、文字列終了とは思わない。ちょっとでもそれを見ていきます。 –

答えて

1
char* filename = (char *)malloc(strlen(version) + strlen(argv[3])); 

最初に、戻り値をmalloc(3)からキャストする必要はありません。プログラムに#include <stdlib.h>を追加すると、malloc(3)の戻り値を正しく処理する方法をコンパイラに指示するプロトタイプmalloc(3)が得られます。それを自分自身でキャストすれば、有用な警告やバグを捕まえることができるエラーを記録することができます。 #includeを追加し、キャストを削除します。

また、ファイル名に十分なメモリが割り当てられていないようです。 strlen(3)でないことを忘れないでください。には、文字列の末尾にASCIIの末尾にNULバイトのスペースが含まれていますが、filenameには必ず終端のNULが必要です。

bar = malloc(strlen(foo)); 

それはほとんど常にバグです:あなたはこのようないくつかのコードを見るたび

。これは、代わりに次のようになります。

bar = malloc(strlen(foo)+1); 

サイズの計算は別の場所で勃発した場合でも、私は多くの場合、ちょうど私はそれが将来的にはそこにある知っていることを確認するために、特にmalloc()コール内+1を置くのが好き。あなたのfile0NULLとき

、あなたはおそらくもは、ファイルを開くことができませんでした、なぜあなたを伝えるためにperror(3)を呼び出す必要があります。それは "許可が拒否されました"かもしれません。現在の作業ディレクトリがもう存在しない可能性があります。 (これにより、ファイルシステムのパーミッションによってファイルを作成することが許可されていても、ディレクトリにファイルを作成することができなくなります)。

+0

答えsarnoldをありがとう。 stdlib.hを先頭に含めていますが、コンパイルするとエラーが発生します:「型 'void *'の値を使用して型 'char *'のエンティティを初期化することはできません。私はgcc auto-links stdlibを知っていますが、そうするためにnvccに指示する必要がありますか?それはnvccがgccを呼び出す方法についての私の理解に基づいて私には正しいように見えません...長さの問題に関しては、char *変数のバージョンから始めているので、私はそれをファイル名に処理します。私は、mallocのstrlen(バージョン)部分がそれを得るのを知っています。私は+1を試みましたが、変化はありません。 –

+0

ああ、perror()はmalloc()をchar *にキャストしているときにコンパイルすると "No such file or directory"を返します。 –

+0

あなたの一番上の編集は 'malloc(3)'キャスティングについて説明しています。私はC++を理解できないことを受け入れなければならないでしょう - それは私にとってはあまりにも異なっています。私はなぜあなたがまだ "そのようなファイルやディレクトリ"を取得しているのか分かりません - あなたはファイル名を印刷してそれが意味をなさないことを確認できますか? – sarnold

関連する問題