メモリ領域の確保について
Posted: 2015年8月21日(金) 20:26
はじめまして。よろしくお願いします。
変数宣言した時にメモリがどのように確保されるのか調べてます。
以下ソース(注:メモリ不正アクセスの不具合があります。)を実行した時、str_Bの先頭バイトが破壊される事象が発生しました。
降順かつ連続した領域に確保されるとデータが破壊されます。(例えばstr_Aが41~80番地、str_Bが1~40番地)
発生したのはSolaris環境ですが、環境が無いため準備出来るWindowsで検証をしていますが再現出来ません。
質問
・VS2008ではアクセス違反コードが有る時と無い時で確保方法が異なるのは何故なのでしょうか?(違反有り:非連続、違反無し:連続)
・アクセス違反部分を削除し実行するとVS2012+x64ビルドだけ降順になるのは何故なのでしょうか?
・VS2012ではアクセス違反部分があると実行エラーになるのは何故なのでしょうか?
以下は検証結果です。
検証環境:Windws7(x64) + VisualStudio
実行環境:検証環境と同じ
■上記コードからアクセス違反部分とmemcpy部分の4行を削除し変数宣言とfprintfだけにして実行した結果
・VS2008、ビルド構成マネージャ:Release + Win32 → 結果:昇順+連続
str_A[1] =003AFC38
str_A[40]=003AFC5F
str_B[1] =003AFC60
str_B[40]=003AFC87
・VS2008、ビルド構成マネージャ:Release + x64 → 結果:昇順+連続
str_A[1] =00000000001DFB00
str_A[40]=00000000001DFB27
str_B[1] =00000000001DFB28
str_B[40]=00000000001DFB4F
・VS2012、ビルド構成マネージャ:Release + Win32 → 結果:降順+連続 ※
str_A[1] =0018FA20
str_A[40]=0018FA47
str_B[1] =0018F9F8
str_B[40]=0018FA1F
・VS2012、ビルド構成マネージャ:Release + x64 → 結果:昇順+連続
str_A[1] =00000000002AF6D0
str_A[40]=00000000002AF6F7
str_B[1] =00000000002AF6F8
str_B[40]=00000000002AF71F
■上記コードを実行した結果(アクセス違反コード有り)
・VS2008、ビルド構成マネージャ:Release + Win32 → 結果:昇順+非連続
str_A[1] =003DFEAC
str_A[40]=003DFED3
str_B[1] =003DFED8
str_B[40]=003DFEFF
・VS2008、ビルド構成マネージャ:Release + x64 → 結果:昇順+非連続
str_A[1] =00000000002AF7C0
str_A[40]=00000000002AF7E7
str_B[1] =00000000002AF7F0
str_B[40]=00000000002AF817
・VS2012、ビルド構成マネージャ:Release + Win32 → 実行エラー
・VS2012、ビルド構成マネージャ:Release + x64 → 実行エラー
よろしくお願いします。
変数宣言した時にメモリがどのように確保されるのか調べてます。
以下ソース(注:メモリ不正アクセスの不具合があります。)を実行した時、str_Bの先頭バイトが破壊される事象が発生しました。
降順かつ連続した領域に確保されるとデータが破壊されます。(例えばstr_Aが41~80番地、str_Bが1~40番地)
発生したのはSolaris環境ですが、環境が無いため準備出来るWindowsで検証をしていますが再現出来ません。
質問
・VS2008ではアクセス違反コードが有る時と無い時で確保方法が異なるのは何故なのでしょうか?(違反有り:非連続、違反無し:連続)
・アクセス違反部分を削除し実行するとVS2012+x64ビルドだけ降順になるのは何故なのでしょうか?
・VS2012ではアクセス違反部分があると実行エラーになるのは何故なのでしょうか?
#include <stdio.h>
#include <string.h>
void main(void)
{
char str_A[40];
char str_B[40];
FILE *fp;
fp = fopen("debug.txt","w");
fprintf(fp, "str_A[1] =%p\n", &str_A[0]);
fprintf(fp, "str_A[%d]=%p\n", sizeof(str_A), &str_A[sizeof(str_A)-1]);
fprintf(fp, "str_B[1] =%p\n", &str_B[0]);
fprintf(fp, "str_B[%d]=%p\n", sizeof(str_B), &str_B[sizeof(str_B)-1]);
str_A[40] = '\0'; /* アクセス違反 */
memcpy(str_A,"0123456789012345678901234567890123456789",40);
str_B[40] = '\0'; /* アクセス違反 */
memcpy(str_B,"0123456789012345678901234567890123456789",40);
fclose(fp);
}
検証環境:Windws7(x64) + VisualStudio
実行環境:検証環境と同じ
■上記コードからアクセス違反部分とmemcpy部分の4行を削除し変数宣言とfprintfだけにして実行した結果
・VS2008、ビルド構成マネージャ:Release + Win32 → 結果:昇順+連続
str_A[1] =003AFC38
str_A[40]=003AFC5F
str_B[1] =003AFC60
str_B[40]=003AFC87
・VS2008、ビルド構成マネージャ:Release + x64 → 結果:昇順+連続
str_A[1] =00000000001DFB00
str_A[40]=00000000001DFB27
str_B[1] =00000000001DFB28
str_B[40]=00000000001DFB4F
・VS2012、ビルド構成マネージャ:Release + Win32 → 結果:降順+連続 ※
str_A[1] =0018FA20
str_A[40]=0018FA47
str_B[1] =0018F9F8
str_B[40]=0018FA1F
・VS2012、ビルド構成マネージャ:Release + x64 → 結果:昇順+連続
str_A[1] =00000000002AF6D0
str_A[40]=00000000002AF6F7
str_B[1] =00000000002AF6F8
str_B[40]=00000000002AF71F
■上記コードを実行した結果(アクセス違反コード有り)
・VS2008、ビルド構成マネージャ:Release + Win32 → 結果:昇順+非連続
str_A[1] =003DFEAC
str_A[40]=003DFED3
str_B[1] =003DFED8
str_B[40]=003DFEFF
・VS2008、ビルド構成マネージャ:Release + x64 → 結果:昇順+非連続
str_A[1] =00000000002AF7C0
str_A[40]=00000000002AF7E7
str_B[1] =00000000002AF7F0
str_B[40]=00000000002AF817
・VS2012、ビルド構成マネージャ:Release + Win32 → 実行エラー
・VS2012、ビルド構成マネージャ:Release + x64 → 実行エラー
よろしくお願いします。