質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.42%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1694閲覧

c言語のメモリの動的確保について

yu_89

総合スコア34

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/04/21 07:53

編集2023/04/25 12:41

実現したいこと

c言語のmallocによるメモリの動的確保について、気になることがあり質問させていただきます。
質問としては、mallocを使いすぎることでメモリを確保する際にmalloc同士で干渉などを起こすことがあるのでしょうか?
といのも、以下のコードでは配列を返す自作関数内でmallocを用いてメモリを動的に確保しており、main関数内ではその自作関数を計11回呼び出しています。このプログラムを実行するとコンパイルはできるのですが、実行すると何度やってもセグメンテーションエラーになり、実行できませんでした。しかし、mallocを使っている関数を一部コメントアウトし、main関数内でもコメントアウトした関数の呼び出し部をコメントアウトして実行すると、エラーにならず実行できました。その後、コメントアウトを解除して実行すると今度はセグメンテーションエラーにならずに実行できました。
このようなことがおきた原因として、malloc同士での干渉があったのかなとも思ったのですが、調べてもあまりピンとくるものがありませんでした。以前にもmallocを大量に使ったプログラム(20個ほどだった気がします。)を書いたのですが、その時は何も問題なく実行できたので、なおさら不思議です。これに関して意見を頂戴したく、質問させていただきました。どなたかわかる方、ご教授のほどよろしくお願いいたします。

該当のソースコード

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#include <string.h> 5 6#define N 1024 7 8int fft1(); 9int window_func(); 10 11void swap(float *x, float *y); 12 13double* freq(void); 14double* CalcPower(double data[]); 15double* Kurtosis(double a[], double b[], double c[], double d[]); 16 17 18int main(int argc,const char *argv[]) 19{ 20 int i, j, k, n, n_frame, iter, flag; 21 int n_frame = 2929; 22 23 char datar[256], datai[256]; 24 25 float ar1[N], ai1[N], ar2[N], ai2[N]; 26 27 double pwr1, pwi1, pwr2, pwi2; 28 29 double dcnt; 30 31 double S1r1[N], S2r1[N], S3r1[N], S4r1[N], S6r1[N]; 32 double S1i1[N], S2i1[N], S3i1[N], S4i1[N]; 33 double Myu1r1[N], Myu2r1[N], Myu3r1[N], Myu4r1[N]; 34 double Myu1i1[N], Myu2i1[N], Myu3i1[N], Myu4i1[N]; 35 36 double S1r2[N], S2r2[N], S3r2[N], S4r2[N], S6r2[N]; 37 double S1i2[N], S2i2[N], S3i2[N], S4i2[N]; 38 double Myu1r2[N], Myu2r2[N], Myu3r2[N], Myu4r2[N]; 39 double Myu1i2[N], Myu2i2[N], Myu3i2[N], Myu4i2[N]; 40 41 double sub_Myu1r[N], sub_Myu2r[N], sub_Myu3r[N], sub_Myu4r[N]; 42 double sub_Myu1i[N], sub_Myu2i[N], sub_Myu3i[N], sub_Myu4i[N]; 43 44 double Myu21[N], Myu22[N], sub_Myu2[N]; 45 double sub_myu2[N], b[N], h[N], h1[N]; 46 double d[N], d1[N]; 47 double sub_d[N]; 48 49 double sub_d_neighbor[N], sub_d_neighbor1[N]; 50 double v[N], v1[N], sub_v[N], sub_v1[N]; 51 52 double modi_Myu2_freq[N]; 53 54 double* fq = NULL; 55 56 double* Kr = NULL; 57 double* Ki = NULL; 58 double* Ka = NULL; 59 double* Kb = NULL; 60 61 double Mr[N], Mi[N], Ma[N], Mb[N]; 62 double Fr[N], Fi[N]; 63 double br[N], bi[N], ba[N], bb[N], qr[N], qa[N]; 64 double xr[N], xi[N], xa[N], xb[N], qi[N], qb[N]; 65 66 double modi_Myu2_kur1[N]; 67 double modi_Myu2_kur2[N]; 68 69 double com[N]; 70 double modi_Myu2_com[N]; 71 72 double* Myu21_power = NULL; 73 double* sub_Myu2_power = NULL; 74 double* modi_power_com = NULL; 75 double* modi_power_kur1 = NULL; 76 double* modi_power_kur2 = NULL; 77 double* modi_power_freq = NULL; 78 79 FILE *fp, *fp1; 80 81 for(i = 0; i < N; i++) 82 { 83 ar1[i] = 0.0; 84 ai1[i] = 0.0; 85 ar2[i] = 0.0; 86 ai2[i] = 0.0; 87 88 Myu21[i] = 0.0; 89 Myu22[i] = 0.0; 90 91 S1r1[i] = 0.0; 92 S1i1[i] = 0.0; 93 S2r1[i] = 0.0; 94 S2i1[i] = 0.0; 95 S3r1[i] = 0.0; 96 S3i1[i] = 0.0; 97 S4r1[i] = 0.0; 98 S4i1[i] = 0.0; 99 100 S1r2[i] = 0.0; 101 S1i2[i] = 0.0; 102 S2r2[i] = 0.0; 103 S2i2[i] = 0.0; 104 S3r2[i] = 0.0; 105 S3i2[i] = 0.0; 106 S4r2[i] = 0.0; 107 S4i2[i] = 0.0; 108 109 Myu1r1[i] = 0.0; 110 Myu1i1[i] = 0.0; 111 Myu2r1[i] = 0.0; 112 Myu2i1[i] = 0.0; 113 Myu3r1[i] = 0.0; 114 Myu3i1[i] = 0.0; 115 Myu4r1[i] = 0.0; 116 Myu4i1[i] = 0.0; 117 } 118 119 pwr1 = 0.0; 120 pwi1 = 0.0; 121 pwr2 = 0.0; 122 pwi2 = 0.0; 123 124 dcnt = 0.0; 125 126 fp = fopen(argv[1],"r"); 127 fp1 = fopen(argv[2],"r"); 128 129 if(fp == NULL) 130 printf("fp:cannnot open file\n"); 131 else 132 printf("fp:open file\n"); 133 134 if(fp1 == NULL) 135 printf("fp1:cannnot open file\n"); 136 else 137 printf("fp1:open file\n"); 138 139 140 iter = 0; 141 flag = 0; 142 143 for(n = 0; n < n_frame; n++) 144 { 145 for(i = 0; i < N; i++) 146 { 147 fgets(datar, sizeof(datar), fp); 148 ar1[i] = atof(datar); 149 ar2[i] = 0.0; 150 } 151 152 for(i = 0; i < N; i++) 153 { 154 fgets(datai, sizeof(datai), fp1); 155 ar2[i] = atof(datai); 156 ai2[i] = 0.0; 157 } 158 159 window_func(ar1, N); 160 window_func(ai1, N); 161 fft1(ar1, ai1, N, iter, flag); 162 163 window_func(ar2, N); 164 window_func(ai2, N); 165 fft1(ar2, ai2, N, iter, flag); 166 167 for(i = 0; i < N/2; i++) 168 { 169 swap(&ar1[i], &ar1[N/2+i]); 170 swap(&ai1[i], &ai1[N/2+i]); 171 swap(&ar2[i], &ar2[N/2+i]); 172 swap(&ai2[i], &ai2[N/2+i]); 173 } 174 175 for(i = 0; i < N; i++) 176 { 177 pwr1 = ar1[i]; 178 pwi1 = ai1[i]; 179 180 S1r1[i] += (double)pwr1; 181 S1i1[i] += (double)pwi1; 182 183 S2r1[i] += pow((double)pwr1, 2.0); 184 S2i1[i] += pow((double)pwi1, 2.0); 185 186 S3r1[i] += pow((double)pwr1, 3.0); 187 S3i1[i] += pow((double)pwi1, 3.0); 188 189 S4r1[i] += pow((double)pwr1, 4.0); 190 S4i1[i] += pow((double)pwi1, 4.0); 191 } 192 193 dcnt++; 194 195 } 196 197 printf("\n"); 198 fclose(fp); 199 fclose(fp1); 200 201 fq = freq(); 202 203 for(i = 0; i < N; i++) 204 { 205 Myu1r1[i] = S1r1[i] / dcnt; 206 Myu1i1[i] = S1i1[i] / dcnt; 207 208 Myu2r1[i] = S2r1[i] / dcnt; 209 Myu2i1[i] = S2i1[i] / dcnt; 210 211 Myu3r1[i] = S3r1[i] / dcnt; 212 Myu3i1[i] = S3i1[i] / dcnt; 213 214 Myu4r1[i] = S4r1[i] / dcnt; 215 Myu4i1[i] = S4i1[i] / dcnt; 216 217 Myu21[i] = Myu2r1[i] + Myu2i1[i]; 218 } 219 220 221Myu21_power = CalcPower(Myu21); 222 sub_Myu2_power = CalcPower(Myu21); 223 224 modi_power_freq = CalcPower(Myu21); 225 226 Kr = Kurtosis(Myu1r1, Myu2r1, Myu3r1, Myu4r1); 227 Ki = Kurtosis(Myu1i1, Myu2i1, Myu3i1, Myu4i1); 228 229 Ka = Kurtosis(Myu1r1, Myu2r1, Myu3r1, Myu4r1); 230 Kb = Kurtosis(Myu1i1, Myu2i1, Myu3i1, Myu4i1); 231 232 modi_power_kur1 = CalcPower(Myu21); 233 modi_power_kur2 = CalcPower(Myu21); 234 235 modi_power_com = CalcPower(Myu21); 236 237 free(fq); 238 free(Kr); 239 free(Ki); 240 free(Ka); 241 free(Kb); 242 free(Myu21_power); 243 free(sub_Myu2_power); 244 free(modi_power_com); 245 free(modi_power_freq); 246 free(modi_power_kur1); 247 free(modi_power_kur2); 248 249 return 0; 250 251} 252 253void swap(float *x, float *y) 254{ 255 float temp; 256 257 temp = *x; 258 *x = *y; 259 *y = temp; 260} 261 262int fft1(float ar[], float ai[], int n, int iter, int flag) 263{ 264 int i, j, it, xp, xp2, k, j1, j2, im1, jm1; 265 double sign, w, wr, wi, dr1, dr2, di1, di2, tr, ti, arg; 266 267 if(n < 2) return(999); 268 269 if(iter <= 0) 270 { 271 iter = 0; 272 i = n; 273 274 while(1) 275 { 276 if((i /= 2) == 0) break; 277 iter++; 278 } 279 } 280 281 j = 1; 282 283 for(i = 0; i < iter; i++) j *= 2; 284 285 if(n != j) return(1); 286 287 if(flag == 1) sign=1.0; 288 else sign=-1.0; 289 290 xp2 = n; 291 292 for(it = 0; it < iter; it++) 293 { 294 xp = xp2; 295 xp2 = xp / 2; 296 w = 3.141592653589793 / xp2; 297 298 for(k = 0; k < xp2; k++) 299 { 300 arg = k * w; 301 wr = cos(arg); 302 wi = sign * sin(arg); 303 i = k - xp; 304 305 for(j = xp; j <= n; j += xp) 306 { 307 j1 = j + i; 308 j2 = j1 + xp2; 309 dr1 = ar[j1]; 310 dr2 = ar[j2]; 311 di1 = ai[j1]; 312 di2 = ai[j2]; 313 tr = dr1 - dr2; 314 ti = di1 - di2; 315 316 ar[j1] = dr1 + dr2; 317 ai[j1] = di1 + di2; 318 ar[j2] = tr * wr - ti * wi; 319 ai[j2] = ti * wr + tr * wi; 320 } 321 } 322 } 323 324 j1 = n / 2; 325 j2 = n - 1; 326 j = 1; 327 328 for(i = 1; i <= j2; i++) 329 { 330 if(i < j) 331 { 332 im1 = i - 1; 333 jm1 = j - 1; 334 tr = ar[jm1]; 335 ti = ai[jm1]; 336 337 ar[jm1] = ar[im1]; 338 ai[jm1] = ai[im1]; 339 ar[im1] = tr; 340 ai[im1] = ti; 341 } 342 343 k = j1; 344 345 while(k < j) 346 { 347 j -= k; 348 k /= 2; 349 } 350 351 j += k; 352 } 353 354 if(flag == 0) return(0); 355 356 w = n; 357 358 for(i = 0; i < n; i++) 359 { 360 ar[i] = ar[i] / w; 361 ai[i] = ai[i] / w; 362 } 363 364 return(0); 365} 366 367 368int window_func(float frame[], int n) 369{ 370 int i; 371 float winv[n]; 372 double pi = 3.141592653589793; 373 374 for(i = 0; i < n; i++) 375 { 376 winv[i] = 0.35875 - 0.48829 * cos(2.0*pi*i/(n-1)) + 0.14128 * cos(4.0*pi*i/(n-1)) - 0.01168 * cos(6.0*pi*i/(n-1)); 377 378 frame[i] = frame[i] * winv[i]; 379 } 380 381 return(0); 382} 383 384double* CalcPower(double data[]) 385{ 386 int i; 387 double av[N]; 388 double* power = (double*)malloc(N * sizeof(double)); 389 390 for(i = 0; i < N; i++) 391 av[i] = 0.0; 392 393 for(i = 0; i < N; i++) 394 { 395 av[i] = data[i] / 1000000; 396 power[i] = 10 * log10(av[i]); 397 } 398 399 return power; 400} 401 402double* Kurtosis(double Myu1[], double Myu2[], double Myu3[], double Myu4[]) 403{ 404 int i; 405 double M1[N], M2[N], M3[N], M4[N]; 406 double top[N], bottom[N]; 407 double* K = (double*)malloc(N * sizeof(double)); 408 409 for(i = 0; i < N; i++) 410 { 411 M1[i] = 0.0; 412 M2[i] = 0.0; 413 M3[i] = 0.0; 414 M4[i] = 0.0; 415 416 top[i] = 0.0; 417 bottom[i] = 0.0; 418 } 419 420 for(i = 0; i < N; i++) 421 { 422 M1[i] = 4.0 * Myu3[i] * Myu1[i]; 423 424 M2[i] = 6.0 * Myu2[i] * Myu1[i] * Myu1[i]; 425 426 M3[i] = 3.0 * Myu1[i] * Myu1[i] * Myu1[i] * Myu1[i]; 427 428 M4[i] = Myu2[i] - (Myu1[i] * Myu1[i]); 429 } 430 431 for(i = 0; i < N; i++) 432 { 433 top[i] = Myu4[i] - M1[i] + M2[i] - M3[i]; 434 bottom[i] = M4[i] * M4[i]; 435 } 436 437 for(i = 0; i < N; i++) 438 { 439 K[i] = top[i] / bottom[i]; 440 } 441 442 return K; 443 444} 445 446double* freq(void) 447{ 448 int i; 449 double* fq = (double*)malloc(N * sizeof(double)); 450 451 for(i = 0; i < N; i++) 452 fq[i] = (875.0 + 6000.0 + (30.0/1024.0) * i) / 1000.0; 453 454 return fq; 455 456}

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <time.h> 4 5#define N 3000000 6 7double GetRandom(); 8 9int main() 10{ 11 int i; 12 FILE *fp, *fp1; 13 14 fp = fopen("rand1.dat", "w"); 15 fp1 = fopen("rand2.dat", "w"); 16 17 srand((unsigned int)time(NULL)); 18 for(i = 0; i < N; i++) 19 { 20 fprintf(fp, "%f\n", GetRandom(0,1)); 21 fprintf(fp1, "%f\n", GetRandom(0,1)); 22 } 23 24 fclose(fp); 25 fclose(fp1); 26 27 return 0; 28} 29 30double GetRandom(int min, int max) 31{ 32 return min + (double)(rand() * (max - min + 1.0) / (1.0 + RAND_MAX)); 33}

補足情報(FW/ツールのバージョンなど)

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2023/04/21 08:12 編集

「malloc同士での干渉」とは何ですか? 何が/どう干渉するんですか?
maisumakun

2023/04/21 08:06

Nを変数でなく#defineで定義してみたらどうなりますでしょうか? (変数で個数を決めてローカル配列を確保するのはVLAといって、これもまた別種の動的確保となります)
tatsu99

2023/04/21 08:09

提示されたソースをコンパイルして、実行すると、どうなるのでしょうか。 又、どうなることを期待されているのでしょうか。
int32_t

2023/04/21 08:39

malloc() の問題というより、ローカル変数多すぎでスタック枯渇かもしれませんね。
Zuishin

2023/04/21 09:33

私もこの程度の malloc でメモリが枯渇するというのは考えにくいと思います。 ローカル変数ならあり得ますね。 しかし、関数呼び出しをコメントアウトして動いたというなら、コメントアウトしなかった場合にはスタックオーバーフローになりそうですが。
jimbe

2023/04/21 09:41 編集

プログラムに問題が一切無いのに malloc で干渉とやらが発生するのなら、 OS がおかしいということになるでしょう。 推測では無く仮説を立ててそれを確認していく作業が必要です。
Zuishin

2023/04/21 09:48 編集

謎なのは、メモリを確保しているのに main で使っていないところです。 処理が省略されているのであれば、そこに問題がある可能性があります。 もしこのコードが問題の起きるコードでないのであれば、こちらでは推測しかできず、質問者側で検証しなければいけません。 もっとも、私はコンパイルも実行もせず斜め読みしただけなので、このコードに問題があるのかどうかすら知りませんが。
yu_89

2023/04/21 09:59

ご回答いただき、ありがとうございます。 episteme様 double* Kurtosis()だけ残してあとの関数をコメントアウトすると実行できて、その後、関数のコメントアウトを全て外して実行すると今度はセグメンテーションフォルトにならずに実行できたので、干渉するというか、mallocを使いすぎるが故にメモリの確保時にバグってエラーになったのかな、そういうこともあるのかなと思いまして。
yu_89

2023/04/21 10:03

ご回答いただき、ありがとうございます。 maisumakun様 #defineで定義しても実行することができました。
yu_89

2023/04/21 10:13 編集

ご回答いただき、ありがとうございます。 int32_t様、Zuishin様 なるほど。やっぱり、ローカル変数は多すぎですかね。コードはだいぶ省略していますが、実際には1000行以上あって極力変数を少なくして書いているつもりなのですが、もう少し、減らせるように工夫してみます。
yu_89

2023/04/21 10:11

ご回答いただき、ありがとうございます。 jimbe様 確かにそうですね。今の段階では憶測に過ぎないので、仮設を立てて検証してみようと思います。
yu_89

2023/04/21 10:15

ご回答いただき、ありがとうございます。 tatsu99様 コードは質問に必要だと思う部分だけを抜き出して載せています。 どうなることを期待するというより、mallocの使いすぎでエラーになることがあるのかどうかとういことが知りたかったので質問させていただきました。
Zuishin

2023/04/21 10:15

変数の数というより、配列がスタックに確保されているんじゃないですか?
Zuishin

2023/04/21 10:18

> コードは質問に必要だと思う部分だけを抜き出して載せています。 「思う」ではなく、ログをとってどこでエラーになっているか調べるのが良いと思います。
melian

2023/04/21 10:38 編集

スタックの使用量に関して言えば、大体 690 kb 程度です。 $ lsb_release -rc Release: 22.04 Codename: jammy $ gcc --version gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 $ gcc -std=gnu2x -Wall -Wextra -g -o calc calc.c -lm $ gdb ./calc (gdb) break 88 Breakpoint 1 at 0x58a3: file calc.c, line 88. (gdb) run Starting program: calc [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, main (argc=1, argv=0x7fffffffe118) at calc.c:88 88 modi_power_freq = CalcPower(sub_Myu2, N); (gdb) p (char *)_environ - (char *)$sp $1 = 709144 heap の使用量(free() の直前)は以下の通り。 (gdb) break 106 (gdb) run (gdb) call malloc_stats() Arena 0: system bytes = 135168 in use bytes = 83776 Total (incl. mmap): system bytes = 135168 in use bytes = 83776 max mmap regions = 0 max mmap bytes = 0
yu_89

2023/04/21 11:25

Zuishin様 確かに、スタックオーバーフロウの可能性もありますね。 なるほど。ログをとってエラーを調べるという方法もあるのですね。調べてやってみます。 ご助言、ありがとうございます。
yu_89

2023/04/21 11:26

ご回答いただき、ありがとうございます。 melian様 gdbで使用量が調べられるのですね。知りませんでした。ありがとうございます。試してみます。
Zuishin

2023/04/21 11:27

ローカル変数が原因の可能性もあるけど、それだとスタックオーバーフローが出るはずなので、ここに書いていない部分に問題があるんじゃないかと書きました。
melian

2023/04/21 11:36 編集

Ubuntu ですと、スタックサイズのデフォルトは 8 MB です。 $ ulimit -s 8192 例えば、スタックサイズを 600 kb にして、件のプログラムを実行すると segmentation fault が発生します。 $ ulimit -s 600 $ ulimit -s 600 $ ./calc Segmentation fault (core dumped)
Zuishin

2023/04/21 12:18

そんなピンポイントなサイズなんですかね。 コメントアウトすれば動くと書いていますが。
yu_89

2023/04/21 12:21

Zuishin様 なるほど、そうだったんですね。ありがとうございます。 melian様が教えてくださった方法やZuishin様が教えてくださったログを取るなどしてエラーのでる原因を調べてみます。
yu_89

2023/04/21 12:24

melian様 確かにスタックサイズをおとして実行すると再びセグメンテーションフォルトになりました。 変数によるスタック枯渇の可能性も大きいかなと思います。
thkana

2023/04/21 13:00

「このプログラムを実行すると何度やっても」私のてもとではエラー出ないのですけど...そのサンプルでSegmentation faultが出ているのですよね? 「実際には1000行以上」あるというのではなく。 (いやまぁ、C/C++ではエラーが表面化するかしないかは運次第、なんてのは普通ですけれど) > double* Kurtosis()だけ残してあとの関数をコメントアウトすると実行できて、その後、関数のコメントアウトを全て外して実行すると今度はセグメンテーションフォルトにならずに実行できた どちらも実行できた、と書いてありますが正しいですか? > mallocの使いすぎでエラーになることがあるのかどうか コンパイラも人間が作ったものですから...というレベルで言うなら絶対大丈夫とは言えませんが、 gccを一体どれだけの人が使っているかを考えると、この程度のプログラムで誤動作が起こるというのは宝くじの特等を連続で引くよりレアなことと思います。そういうレベルで「そんなことはない」と言っていいのでは。
thkana

2023/04/21 13:05

え? 結局「なにが原因だった」のですか? ちゃんと筋道が通る説明はあるのですか?
yu_89

2023/04/24 02:28

thkana様 ご回答いただき、ありがとうございます。また、返信が遅れてしまい、申し訳ございません。 >そのサンプルでSegmentation faultが出ているのですよね? いえ、エラーが出ていたのは手元にある元のコードです。質問の主旨としてはmallocの使いすぎが原因でエラーが出るのか、ということをお聞きしたかったので、それに必要だと考えられる部分を抜き出して提示しました。しかし、やはり質問する以上、元のコードも提示するべきでしたね。申し訳ございません。元のコードも提示しておきます。 >どちらも実行できた、と書いてありますが正しいですか? はい、正しいです。試した結果、それで動くようになりました。 > gccを一体どれだけの人が使っているかを考えると、この程度のプログラムで誤動作が起こるというのは宝くじの特等を連続で引くよりレアなことと思います。 なるほど、やはりmallocの使いすぎによる誤作動は考えにくいですかね。 >結局「なにが原因だった」 スタックサイズを変更して実行した所、セグメンテーションフォルトしたので、ローカル変数の使いすぎによるものだったと考えました。
yu_89

2023/04/24 02:58

元のコードは省ききれなかったため、提示するのを断念します。申し訳ございません。
thkana

2023/04/24 22:52

https://teratail.com/help/question-tips#questionTips35 「最も良いのは、現象を再現するためのミニマムなプログラムを改めて作ることです。」 スタックサイズを変化することで現象が出たり出なかったりする、というのはとても有力な情報であるのは確かですが、それ「だけ」が原因であったとすれば > #defineで定義しても実行することができました。 は説明できるのでしょうか? 説明できないとすれば、地雷がちらと見えたのに土を被せて見なかったことにするような行為かも知れません。
Zuishin

2023/04/24 23:08

スタックサイズが十分あると思われた時に発生した問題なので、スタックサイズを小さくして同じエラーが出たというのは解決の何の根拠にもなっていません。 ベストアンサーに選ばれているのもスタックと無関係のものだし、質問自体からも思い込みの強さが感じられます。 回答者が自分にマウントを取るために重箱の隅をつついて言わなくていいことをゴチャゴチャ言っているくらいの認識なのでしょう。
thkana

2023/04/24 23:38

質問者さんが「スタックサイズ」から思考が離れなくなってしまって、仮説に反するかも知れない情報を直視できないでいるのはそうなんだけど、それは多分、自分がコレだと思ったのと全然違うところに真の原因があったという「痛い目」を見たことがないという経験不足、スキル不足からくるものじゃないかと思うのです。 回答のコメントのやり取りでメモリ確保のチェックにさっと対応している辺り、素直な人という印象を私は持ちましたよ。
melian

2023/04/25 01:17

先に述べました様に、現状のスタックの使用量は 690 KB 程度で、Ubuntu のデフォルトのスタックサイズは 8 MB です。なので、N の値を 1024 ではなく 13650 程度以上にするとセグメンテーションフォールトが発生します。 int N = 1024; => int N = 13650; 憶測ですが、元々は N の値をかなり大きな値に設定していたのではないでしょうか。
Zuishin

2023/04/25 01:31

質問には省略されている部分があるので、ハードコーディングされている数値が違っていると言うよりは省略されている部分を先に疑うべきかと。
Zuishin

2023/04/25 01:35 編集

セグメンテーション違反がスタックサイズでしか起こりえないなら話は別ですが、ここではそれは原因の可能性の一つにすぎず、しかも掲載されているコードや質問者の開示した情報のみから判断するなら、そこまで可能性が高いようには見えません。 なので、本当にそこで解決したと断定していいのかという話が今進んでいるところです。
Zuishin

2023/04/25 01:36

繰り返しになりますが、同じエラーが起こることは同じ原因であることを証明しません。
yu_89

2023/04/25 10:39

コードを文字数制限ギリギリまで可能な限り載せました。 Nは1024よりは大きくして実行したことはないので、その可能性はないと考えられます。 確かに少し考えれば、今回の場合はスタックサイズが十分あると考えられる状態でセグメンテーション違反が発生してるので、スタックサイズを小さくして試して出るのはエラーが出るのは、何の根拠にもなりませんよね。真の原因から目を背けてました。 ただ、今は問題なく動いているので、ここからどうやってエラーが出た原因を探ればいいのか考えあぐねています。
melian

2023/04/25 11:10

記載のコードにはファイルからデータを読み込む処理があるのですが、ファイルポインタが NULL がどうかをチェックしていません。引数に何も指定していなかったり、存在しないファイルを指定すれば、後の fgets() で segmentation fault が発生するでしょう。 fp = fopen(argv[1],"r"); fp1 = fopen(argv[2],"r");   : fgets(datar, sizeof(datar), fp);   : fgets(datai, sizeof(datai), fp1);
yu_89

2023/04/25 12:39

ファイルポインタのNULLチェックをするのを忘れてました。 間違ったファイルを知らずに入力していたかもしれません。それも原因の一ですね。 入れておきます。ありがとうございます。
guest

回答3

0

ベストアンサー

メモリを大量に使いすぎて、残りが足らなければ、mallocの実行が失敗することがあります。
mallocの実行時は、成功したか失敗したかを必ずチェックする必要がありますよ

投稿2023/04/21 08:14

y_waiwai

総合スコア87885

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu_89

2023/04/21 09:44

回答いただき、ありがとうございます。 確かにそうですね。メモリの確保に成功したか失敗したかの確認を怠っていました。 エラーになる理由を何時間も考えていたのですが、確認していれば、すぐに解決できたかもしれません。 次からは確認しながら使います。 ご助言、ありがとうございます。
thkana

2023/04/21 13:06

> 次からは確認しながら使います。 だめです。 「今から」確認するプログラムにしましょう。
yu_89

2023/04/24 03:03

そうですよね。「今から」すべきですよね。mallocでメモリの確保ができたかどうかを確認できるプログラムに変更して実行した所、メモリの確保ができていました。なので、やはり、ローカル変数の使いすぎによるエラーの可能性が大きいと考えます。
guest

0

私の解答は間違っていました。すみません。

NULL for free しようとしているからではないですかね。

double* fq = NULL; はアサインされてませんね。

投稿2023/04/24 23:28

編集2023/04/25 00:26
NANASHI-TAROU

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2023/04/24 23:43

NULLポインタに対するfree()は「なにもしない(エラーにもならない)」ことが保証されているはずです。
NANASHI-TAROU

2023/04/25 00:01

double freeと混同してました。ご指摘ありがとうございます。
guest

0

malloc()free() を正しく使っていれば使い過ぎて誤動作するということはまずありません。質問文のコードでは malloc() の返り値チェックがないぐらいで、範囲外アクセスも見当たりませんので malloc() を使っていることが原因で問題が起きている可能性は極めて低いでしょう。

大量のローカル変数を使っていることがトラブルの原因になることがあります。ローカル変数はスタック上に確保されますが、スタックのサイズ限界はそんなに大きくないことがあります。スタックが枯渇していると、関数呼び出しをした瞬間にクラッシュするなどの症状が出ます。
Ubuntu でしたら、ulimit -s コマンドでスタックの最大サイズを知ることができます。大きな配列はグローバル変数にしたり、それこそ malloc() で確保するようにしましょう。

投稿2023/04/23 21:37

int32_t

総合スコア21296

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu_89

2023/04/24 03:07

ご回答いただき、ありがとうございます。 やはり、mallocが原因である可能性は低いですかね。 スタックサイズを変更して実行した所、セグメンテーションファルトになったので、やはりローカル変数の使いすぎによるエラーだったのかなと考えます。 グローバル変数にするかmallocで確保するようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.42%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問