স্ট্যাটিক ইন্ট আরআর [10] মেমরি ঠিকানা সর্বদা 060 এ শেষ হয়


17

আমার কাছে এসি প্রোগ্রাম রয়েছে যা দেখতে এটির মতো

main.c

#include <stdio.h>
#define SOME_VAR 10

static int heap[SOME_VAR];


int main(void) {
    printf("%p", heap);
    return 0;
}

এবং যখন আমি কয়েকবার সংকলিত প্রোগ্রামটি চালিত করি তখন এটি আউটপুট হয়

0x58aa7c49060
0x56555644060
0x2f8d1f8e060
0x92f58280060
0x59551c53060
0xd474ed6e060
0x767c4561060
0xf515aeda060
0xbe62367e060

কেন সর্বদা 060 এ শেষ হয়? এবং অ্যারে গাদা জমা আছে?

সম্পাদনা: আমি লিনাক্সে আছি এবং আমার এএসএলআর চালু আছে। আমি জিসিসি ব্যবহার করে প্রোগ্রামটি সংকলন করেছি


2
কী অপারেটিং সিস্টেম? কি সংকলন?
অ্যান্ড্রু হেনেল

2
পরিবর্তনশীল, গাদা নয় এটা প্রোগ্রামের অ্যাড্রেস স্পেস এর ডেটা বা বাসস অধ্যায় আছে, দেখতে en.wikipedia.org/wiki/Static_variable । আমার অনুমান যে প্রোগ্রামটি সর্বদা একটি নির্দিষ্ট সীমানায় মেমরি ঠিকানায় স্থাপন করা হবে, উদাহরণস্বরূপ 0x1000 দ্বারা বিভাজ্য এবং ভেরিয়েবলটি প্রোগ্রামারের ঠিকানার জায়গার একটি স্থির অফসেটে সংকলক দ্বারা স্থাপন করা হয়।
বোডো

উত্তর:


15

ঠিকানাগুলি এএসএলআর (অ্যাড্রেস স্পেস লেআউট রমডাইজেশন) এর কারণে পৃথক হয়। এটি ব্যবহার করে, বাইনারিটি ভার্চুয়াল ঠিকানা জায়গার বিভিন্ন স্থানে ম্যাপ করা যায়।

চলকটি heapহ'ল - এর নামের বিপরীতে - গাদাতে নয়, তবে অবস্থিত bss। ঠিকানার জায়গাতে অফসেট তাই ধ্রুবক।

পৃষ্ঠাগুলি পৃষ্ঠার গ্রানুলারিটিতে ম্যাপ করা হয় যা বহু প্ল্যাটফর্মে 4096 বাইট (হেক্স: 0x1000) হয়। এই কারণেই, কেন ঠিকানাটির শেষ তিনটি হেক্স ডিজিট একই।

আপনি যখন স্ট্যাক ভেরিয়েবলের সাথে একই কাজটি করেছিলেন , ঠিকানাটি কিছু প্ল্যাটফর্মের সর্বশেষ অঙ্কগুলিতে (সাম্প্রতিক কার্নেলের সাথে লিনাক্স) এমনকি পৃথক হতে পারে, কারণ স্ট্যাকটি অন্য কোথাও ম্যাপ করা হয় না তবে এটি শুরুতে একটি এলোমেলো অফসেট পায়।


ASLR লোডিংয়ের ভিত্তিটি এলোমেলোভাবে মনে পড়ছে remember বিভাগের ঠিকানা সেই ঠিকানার উপর ভিত্তি করে।
আফশিন

আমি অ্যাক্সেল-থোবিয়াস শ্রেইনার দ্বারা অবজেক্ট অরিয়েন্টেড এএনএসআই-সি প্রোগ্রামিংয়ের একটি বই ব্যবহার করছি। বইটি 1993 এর মতো কিছুতে লেখা হয়েছে you আপনি কি জানেন যে স্মৃতি বিন্যাসটি তখন আলাদা ছিল কিনা? যদি এটি না হয় তবে তিনি কেন ভেরিয়েবলটির নাম রাখতেন heapযখন এটি গাদা না থাকে?
linuxlmao

4096 কি কোনও উপায়ে 060 এ অনুবাদ করে বা 0x1000 060 এ অনুবাদ করে নাহলে আমি বুঝতে পারি না যে আপনি শেষ হওয়ার কারণ হিসাবে কী বোঝাতে চেয়েছেন? আমি ভেবেছিলাম এটি অ্যারের আকারের সাথে কিছু হতে পারে যা হেক্সাডেসিমাল থেকে 060 তে অনুবাদ করা হয়েছে, যেমন দশমিক
লিনাক্স্লমাও

2
@linuxlmao অফসেটটি উদাহরণস্বরূপ 14060, সুতরাং আপনি যখন কোনও পৃষ্ঠার আকারের (0x1000) একাধিক যুক্ত করেন, শেষ তিনটি সংখ্যা বাকি থাকে 060
Ctx

4

আপনি যদি উইন্ডোজ ব্যবহার করেন তবে কারণটি পিই কাঠামো।

আপনার heapভেরিয়েবলটি .dataফাইলের বিভাগে সঞ্চিত আছে এবং এই বিভাগের সূচনার ভিত্তিতে এর ঠিকানা গণনা করা হয়। প্রতিটি বিভাগ একটি ঠিকানাতে স্বাধীনভাবে লোড করা হয়, তবে এর সূচনা ঠিকানা পৃষ্ঠার আকারের একাধিক। আপনার অন্য কোনও ভেরিয়েবল না থাকায়, এর ঠিকানা সম্ভবত .dataবিভাগের শুরু , সুতরাং এর ঠিকানাটি আকারের একাধিক হবে।

উদাহরণস্বরূপ, এটি আপনার কোড কম্পাইল উইন্ডোজ সংস্করণের টেবিল: বিভাগটি আপনার কম্পাইল কোড এবং করছিলেন আপনার ধারণ করে পরিবর্তনশীল। যখন আপনার পিই মেমরিতে লোড হয়, বিভাগগুলি বিভিন্ন ঠিকানায় লোড হয় এবং যা দ্বারা ফিরে আসে এবং পৃষ্ঠার আকারের একাধিক হবে। তবে প্রতিটি ভেরিয়েবলের ঠিকানা বিভাগের সূচনার সাথে সম্পর্কিত যা এখন পৃষ্ঠার আকার। সুতরাং আপনি সর্বদা কম সংখ্যায় একটি নির্দিষ্ট নম্বর দেখতে পাবেন। যেহেতু বিভাগের সূচনা থেকে আপেক্ষিক ঠিকানা সংকলক, সংকলন বিকল্প ইত্যাদির উপর ভিত্তি করে আপনি একই কোড থেকে ভিন্ন সংখ্যক দেখতে পাবেন তবে বিভিন্ন সংকলক, তবে প্রতিবার যা মুদ্রণ করা হবে তা স্থির করা হবে।বিভাগে.text.dataheapVirtualAlloc()heap

যখন আমি কোডটি সংকলন করি তখন আমি লক্ষ্য করেছি heapযে বিভাগটি 0x8B0শুরু হওয়ার পরে বাইটে রাখা হয়েছে .data। সুতরাং যতবারই আমি এই কোডটি চালাই, আমার ঠিকানাটি শেষ হয় 0x8B0


আমি অ্যাক্সেল-থোবিয়াস শ্রেইনার দ্বারা অবজেক্ট অরিয়েন্টেড এএনএসআই-সি প্রোগ্রামিংয়ের একটি বই ব্যবহার করছি। বইটি 1993 এর মতো কিছুতে লেখা হয়েছে you আপনি কি জানেন যে স্মৃতি বিন্যাসটি তখন আলাদা ছিল কিনা? যদি এটি না হয় তবে তিনি কেন ভেরিয়েবলটির নাম রাখতেন heapযখন এটি গাদা না থাকে?
linuxlmao

2
@linuxlmao এটি ভাল হতে পারে। 1993 সালে, উইন্ডোজ একটি 16-বিট অপারেটিং সিস্টেম ছিল, মেমরি বিভাজন এবং সমস্ত ধরণের বিভ্রান্তিকর সামগ্রী সহ। এটি এখনকার মতো 32-বিট, ফ্ল্যাট-মেমরি আর্কিটেকচার ছিল না । তবে এই ধরণের বিষয়গুলি মেমরিতে কোনও বাইনারি প্রোগ্রামের বিন্যাস সম্পর্কে সাধারণ প্রশ্ন জিজ্ঞাসা / উত্তর দেওয়া কেন কার্যকর নয়। সি ভাষার মানটি আপনাকে সাধারণভাবে কী গ্যারান্টি দেয় এবং তা আপনার জানা দরকার। আপনি যদি কোনও নির্দিষ্ট সমস্যা ডিবাগ করেন তবে কেবল আসল বিন্যাস সম্পর্কে চিন্তা করুন, তবে একটি ডিবাগারটি ব্যবহার করুন
কোডি গ্রে

না, ভেরিয়েবলটি পুরানো সিস্টেমে এমনকি
গাদাতে

@ আফশিন আমি ওপির মন্তব্যে উপরের দিকে সম্বোধন করছি
ফুচলভ

@ ফুচলভ দুঃখিত, কারণ আপনি তাঁর কথা উল্লেখ করেননি, আমি ভেবেছিলাম আপনি আমাকে সম্বোধন করছেন। :)
আফশিন

4

কম্পাইলার করা ঘটেছে heapকম্পাইলার যেমন কোডটি শুরু দ্বারা ব্যবহৃত ডেটা হিসাবে প্রথম 0x60 বাইট, কিছু অন্যান্য উপাদান রয়েছে, কারণ একটি ডাটা সেগমেন্ট এটা আছে মধ্যে অফসেট 0x60 বাইট এ সম্ভবত mainরুটিন। এজন্য আপনি "060" দেখছেন; এটি যেখানে ঘটেছিল ঠিক সেখানেই এটির পক্ষে বড় কোনও তাত্পর্য নেই।

অ্যাড্রেস স্পেস লেআউট র্যান্ডমাইজেশন প্রোগ্রামের মেমোরির বিভিন্ন অংশের জন্য ব্যবহৃত বেস ঠিকানা (এস) পরিবর্তিত করে তবে 0x1000 বাইটের ইউনিটগুলিতে এটি সর্বদা হয় (কারণ এটি প্রান্তিককরণ এবং অন্যান্য সমস্যাগুলির সাথে সমস্যা সৃষ্টি করে) সুতরাং আপনি ঠিকানাগুলি 0x1000 এর গুণমান দ্বারা ওঠানামা করতে দেখেন, তবে শেষ তিনটি সংখ্যা পরিবর্তন হয় না।

সংজ্ঞা static int heap[SOME_VAR];সংজ্ঞায়িত heapস্ট্যাটিক স্টোরেজ সময়কাল সঙ্গে। সাধারন সি প্রয়োগকারীগুলি এটিকে সাধারণ তথ্য বিভাগে সঞ্চয় করে, গাদাতে নয়। "হিপ" মেমরির জন্য একটি ভুল ধারণা যা গতিশীল বরাদ্দ জন্য ব্যবহৃত হয়। (এটি একটি মিসনোমর কারণ mallocবাস্তবায়নগুলি বিভিন্ন ধরণের ডেটা স্ট্রাকচার এবং অ্যালগরিদমগুলি ব্যবহার করতে পারে, স্তূপগুলির মধ্যে সীমাবদ্ধ নয় They এমনকি তারা একটি বাস্তবায়নে একাধিক পদ্ধতিও ব্যবহার করতে পারে))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.