[解決済み] サイズ 1 の無効な書き込み
2022-02-05 14:16:44
質問
パラメータに従って元の文字列を文字列の配列に保存された複数の文字列に分割する私の分割関数の大部分を修正しました:プログラムは私が欲しかった値を返しますが、valgrindは私に次のようにヒットしました。
abc,defg
pasa
pasa
pasa
pasa
pasa
pasa
pasa
pasa
pasa
==2938== Conditional jump or move depends on uninitialised value(s)
==2938== at 0x4C2DB3C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2938== by 0x400912: split (strutil.c:31)
==2938== by 0x400A06: main (strutil.c:45)
==2938== Uninitialised value was created by a stack allocation
==2938== at 0x400723: split (strutil.c:9)
==2938==
==2938== Conditional jump or move depends on uninitialised value(s)
==2938== at 0x4C31577: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2938== by 0x40097F: split (strutil.c:34)
==2938== by 0x400A06: main (strutil.c:45)
==2938== Uninitialised value was created by a stack allocation
==2938== at 0x400723: split (strutil.c:9)
==2938==
==2938== Conditional jump or move depends on uninitialised value(s)
==2938== at 0x4C31631: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2938== by 0x40097F: split (strutil.c:34)
==2938== by 0x400A06: main (strutil.c:45)
==2938== Uninitialised value was created by a stack allocation
==2938== at 0x400723: split (strutil.c:9)
==2938==
==2938== Conditional jump or move depends on uninitialised value(s)
==2938== at 0x4C3164F: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2938== by 0x40097F: split (strutil.c:34)
==2938== by 0x400A06: main (strutil.c:45)
==2938== Uninitialised value was created by a stack allocation
==2938== at 0x400723: split (strutil.c:9)
==2938==
==2938==
==2938== More than 10000000 total errors detected. I'm not reporting any more.
==2938== Final error counts will be inaccurate. Go fix your program!
==2938== Rerun with --error-limit=no to disable this cutoff. Note
==2938== that errors may occur in your program without prior warning from
==2938== Valgrind, because errors are no longer being displayed.
==2938==
abc
defg
そして、私のコードは
#include "strutil.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char** split(const char* str, char sep){
size_t cant = 2;
size_t i = 0;
for(i = 0; i < strlen(str); i++){
if(str[i] == sep)
cant ++;
}
size_t corte[cant];
corte[0] = 0;
size_t j = 1;
size_t cant_corte[cant];
for(i = 0; i < cant; i++)
cant_corte[i] = 0;
for(i = 0; i <= strlen(str); i++){
if(str[i] == sep || str[i] == '\0'){
corte[j] = i + 1;
cant_corte[j - 1] = corte[j] - corte[j - 1];
j++;
}
}
char** strv = malloc(sizeof(char*) * cant);
if (strv == NULL)return NULL;
for(i=0; i < cant; i++){
strv[i] = malloc(sizeof(char) * cant_corte[i]); //line 30
if (strv[i] == NULL)return NULL;
memcpy(strv[i], str + corte[i], cant_corte[i]);
strv[i][cant_corte[i] -1] = '\0'; //line 33
}
strv[cant - 1] = NULL;
return strv;
}
int main(){
char* eje = "abc,defg";
printf("%s\n", eje);
char r = ',';
char** prueba = split(eje, r);
printf("%s\n", prueba[0]);
printf("%s\n", prueba[1]);
getchar();
return 0;
}
同じ値で問題が発生しているように見えますが、問題が見つからないので、どこに問題があるのかわかりません。
EDIT コードを編集したら、valgrind が私を表示するようになりました。
==3751== Invalid write of size 1
==3751== at 0x4009DB: split (strutil.c:33)
==3751== by 0x400A64: main (strutil.c:43)
==3751== Address 0x520457f is 1 bytes before a block of size 0 alloc'd
==3751== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3751== by 0x400949: split (strutil.c:30)
==3751== by 0x400A64: main (strutil.c:43)
30行目のmallocに+1を追加してみましたが、代わりに ...block of size 1 aloc'd... と表示されました。と表示されてしまいます。
解決方法は?
で終わってしまう。
cant_corte[i]
は
0
を、そして、あなたは
strv[i][cant_corte[i] -1] = '\0';
だから
strv[i][-1]
は書き込むのに有効なアドレスではありません。
の使い方を学ぶことをお勧めします。
valgrind
と
gdb
で説明しているように
http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-simple
関連
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み] clang: error: linker command failed with exit code 1が表示されるのはなぜですか?
-
[解決済み] テスト
-
[解決済み】「構造体でもユニオンでもないものにメンバー'*******'を要求する」とはどういう意味ですか?
-
[解決済み】サイズ8の無効な読み取り - Valgrind + C
-
[解決済み] [Solved] .Cファイルをコンパイルしています。アーキテクチャ x86_64 の未定義シンボル
-
[解決済み】インクリメントオペランドとして lvalue が必要です。
-
[解決済み】未定義参照 makefile が間違っているのかも?
-
[解決済み】警告:式の結果が未使用の場合
-
[解決済み】Linuxソケットのwrite()でBad File Descriptorが発生するC
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Cコンパイルエラー。"変数サイズのオブジェクトが初期化されていない可能性がある"
-
[解決済み】C 言語の添え字で配列の要素値を代入すると、配列でもポインタでもベクトルでもない値になる
-
[解決済み】valgrind - サイズ8のブロックが割り当てられた後、アドレス ---- が0バイトになる。
-
[解決済み] Connect: ソケット以外でのソケット操作
-
[解決済み】エラー:'for'ループの初期宣言はC99モードでしかできない【重複
-
[解決済み】スレッド1:EXC_BAD_ACCESS(コード=1、アドレス=0x0)標準Cメモリ問題
-
[解決済み】EAGAINとはどういう意味ですか?
-
[解決済み】LinuxのI_PUSHに相当するもの
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み] エラー: `itoa` はこのスコープで宣言されていません。