সি এবং সি ++ এ স্ট্যাটিক ভেরিয়েবলগুলি কোথায় সংরক্ষণ করা হয়?


180

এক্সিকিউটেবল ফাইলের কোন বিভাগে (.BSS,। ডেটা, অন্যান্য) স্ট্যাটিক ভেরিয়েবলগুলি সংরক্ষণ করা হয় যাতে তাদের নাম সংঘর্ষ না হয়? উদাহরণ স্বরূপ:


foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

আমি যদি উভয় ফাইল সংকলন করি এবং এটিকে একটি মূলের সাথে লিঙ্ক করি যা ফুস্টেস্ট () এবং বারটেষ্টকে বারবার কল করে, প্রিন্টফের বিবৃতি স্বাধীনভাবে বৃদ্ধি করে। Foo এবং বার ভেরিয়েবলগুলি অনুবাদ ইউনিটে স্থানীয় হওয়ায় এটিকে বোঝায়।

তবে স্টোরেজ বরাদ্দ কোথায়?

স্পষ্টরূপে, অনুমানটি হ'ল আপনার কাছে এমন একটি সরঞ্জামচেইন রয়েছে যা কোনও ফাইলকে ELF ফর্ম্যাটে আউটপুট দেয়। সুতরাং, আমি বিশ্বাস করি যে হয়েছে কিছু জায়গা ঐ স্ট্যাটিক ভেরিয়েবলের জন্য এক্সিকিউটেবল ফাইল সংরক্ষিত হতে পারে।
আলোচনার উদ্দেশ্যে, ধরে নিই আমরা জিসিসির সরঞ্জামচেইনটি ব্যবহার করি।


1
বেশিরভাগ লোকেরা আপনাকে বলছে যে সেগুলি আপনার প্রশ্নের উত্তর দেওয়ার পরিবর্তে .ডাটা বিভাগে সংরক্ষণ করা উচিত: ঠিক কোথায় .ডাটা বিভাগে এবং আপনি কোথায় পাবেন find আমি দেখেছি আপনি ইতিমধ্যে একটি উত্তর চিহ্নিত করেছেন, সুতরাং আপনি এটি ইতিমধ্যে জানেন কীভাবে এটি সন্ধান করবেন?
lukmac

কেন ইনিশিয়ালাইজ এবং uninitialised বিভিন্ন বিভাগে স্থাপিত হয়: linuxjournal.com/article/1059
mhk

1
রানটাইমে আপনার গ্লোবাল / স্ট্যাটিক ভেরিয়েবলগুলিতে বরাদ্দকৃত স্টোরেজটির নাম রেজোলিউশনের সাথে কিছুই করার নেই, যা বিল্ড / লিংক সময় ঘটে happens এক্সিকিউটেবলটি নির্মিত হওয়ার পরে - আর কোনও নাম নেই।
ভালডো

2
এই প্রশ্নটি অর্থহীন, অসম্পূর্ণ প্রতীকগুলির "নামের সংঘর্ষ" এমন একটি জিনিস যা বিদ্যমান থাকতে পারে the এমন মিথ্যা ভিত্তিতে নির্মিত। কোনও বৈধ প্রশ্ন নেই বলেই কিছু উত্তরের উত্তর কতটা ভয়াবহ তা ব্যাখ্যা করতে পারে। বিশ্বাস করা খুব কঠিন যে খুব কম লোকই এটি পেয়েছিল।
আন্ডারস্কোর_ডি

উত্তর:


131

যেখানে আপনার স্ট্যাটিকসগুলি সেগুলি শূন্য-আরম্ভ হয় কিনা তার উপর নির্ভর করে । জিরো- ইনিশিয়েলাইজড স্ট্যাটিক ডেটা Bুকে পড়ে .বিএসএস (সিম্বল দিয়ে ব্লক শুরু করা) , অ-শূন্য- আরম্ভকৃত ডেটা .ুকে যায়


50
"অ -0 টি আরম্ভিত" দ্বারা আপনি সম্ভবত "আরম্ভিত, তবে 0 ছাড়া অন্য কিছু দিয়ে" বোঝাতে পারেন। কারণ C / C ++ এ "অ প্রাথমিককরণ" স্ট্যাটিক ডেটা বলে কিছুই নেই। সমস্ত স্থিতিশীল ডিফল্টরূপে শূন্য-আরম্ভ হয়।
অ্যান্ট

21
@ ডন নিউফিল্ড: আপনার উত্তরটি প্রশ্নের কোনও উত্তর দেয় না। কেন এটি গৃহীত হয়েছে তা আমি বুঝতে পারি না। কারণ 'foo' এবং 'বার' উভয়ই অ -0 টি আরম্ভ করা হয়েছে। প্রশ্নটি হ'ল .bss বা .ডাটাতে একই নামের সাথে দুটি স্থিতিশীল / গ্লোবাল ভেরিয়েবল কোথায় রাখবেন
লুকম্যাক

আমি বাস্তবায়নগুলি ব্যবহার করেছি যেখানে স্পষ্টভাবে শূন্য-সূচনাযুক্ত স্ট্যাটিক ডেটা dataুকে পড়েছিল .dataএবং কোনও প্রারম্ভকালীন স্ট্যাটিক ডেটা .ুকে যায় না .bss
এমএম

1
@ এমএম আমার ক্ষেত্রে স্থিতিশীল সদস্য নির্বিঘ্নিত (স্পষ্টভাবে প্রাথমিকভাবে 0 থেকে শুরু করা) বা 0 এ স্পষ্টভাবে আরম্ভ করা হয়েছে, উভয় ক্ষেত্রেই এটি বিএস বিভাগে যুক্ত হয়েছে।
সিবাইন্ডার

এই তথ্য একটি নির্দিষ্ট নির্বাহযোগ্য ফাইল টাইপ নির্দিষ্ট? আমি ধরে নিই, যেহেতু আপনি নির্দিষ্ট করেন নি, এটি অন্তত ELF এবং উইন্ডোজ পিই এক্সিকিউটেবল ফাইলের ক্ষেত্রে প্রযোজ্য, তবে অন্যান্য ধরণের কী হবে?
জেরি যেরেমিয়া

116

যখন কোনও প্রোগ্রাম মেমোরিতে লোড হয়, তখন এটি বিভিন্ন বিভাগে সংগঠিত হয়। বিভাগটির মধ্যে একটি হ'ল ডেটা বিভাগ । ডেটা বিভাগটি আরও দুটি ভাগে বিভক্ত:

আরম্ভিত ডেটা বিভাগ: সমস্ত গ্লোবাল, স্ট্যাটিক এবং ধ্রুবক ডেটা এখানে সংরক্ষণ করা হয়।
অবিশ্রুত ডেটা সেগমেন্ট (বিএসএস): সমস্ত অবিশ্রুত ডেটা এই বিভাগে সংরক্ষণ করা হয়।

এই ধারণাটি ব্যাখ্যা করার জন্য এখানে একটি চিত্র রয়েছে:

এখানে চিত্র বর্ণনা লিখুন


এই ধারণাগুলি ব্যাখ্যা করার জন্য এখানে খুব ভাল লিঙ্ক রয়েছে:

http://www.inf.udec.cl/~leo/teoX.pdf


উপরের উত্তরটি বলেছে 0 আরম্ভ করা বিএসএসে চলে। 0 ইনিশিয়াল মানে কি অবিচ্ছিন্ন বা প্রতি সেউ 0? যদি এর অর্থ প্রতি সেফ 0 হয় তবে আমি মনে করি এটি আপনার উত্তরে অন্তর্ভুক্ত করা উচিত।
ভিরাজ

কনস্ট্যান্ট ডেটা .ডাটা সেগমেন্টে সংরক্ষণ করা হয় না তবে টেক্সট বিভাগের সর্বনিম্ন বিভাগের মধ্যে।
ব্যবহারকারী 10678

এর পরিবর্তে (" প্রারম্ভিক ডেটা বিভাগ) : সমস্ত গ্লোবাল, স্ট্যাটিক এবং ধ্রুবক ডেটা এখানে সংরক্ষণ করা হয় Un একীকরণবিহীন ডেটা বিভাগ (বিএসএস) : সমস্ত অবিস্মরণীয় ডেটা এই বিভাগে সংরক্ষণ করা হয়।"), আমার মনে হয় এটি বলা উচিত: "" আরম্ভিত ডেটা বিভাগ : সমস্ত গ্লোবাল এবং স্ট্যাটিক ভেরিয়েবলগুলি যা একটি শূন্য- অমূল্য এবং সমস্ত ধ্রুবক ডেটা থেকে শুরু হয়েছিল, এখানে সঞ্চিত রয়েছে। অবিশ্রুত ডেটা সেগমেন্ট (বিএসএস) : সমস্ত বৈশ্বিক এবং স্ট্যাটিক ভেরিয়েবলগুলি যা আরম্ভ করা হয়নি, বা আরম্ভ করা হয়নি শূন্য থেকে, এই বিভাগে সংরক্ষণ করা হয়। ")।
গ্যাব্রিয়েল স্টেপলস

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

সুতরাং আমি এই চিত্রটি থেকে যা সংগ্রহ করছি তা হ'ল বৈকল্পিকগুলি যা বৈশ্বিক বা স্থির (যেহেতু স্থির ভেরিয়েবলগুলি বিশ্বব্যাপী ভেরিয়েবলের মতো সময়কালে কাজ করে) না গাদা বা স্ট্যাকের উপর নির্ভর করে না , বরং উভয়টি বাদ দিয়ে স্মৃতিতে বরাদ্দ করা হয়। এটা কি সঠিক? আমি মনে করি আমি আরও একটি স্মৃতি বরাদ্দ অধ্যয়ন করতে আবার একটি এসটিএম 32 লিঙ্কার স্ক্রিপ্ট একবার দেখতে পারেন।
গ্যাব্রিয়েল স্ট্যাপলস

32

আসলে, একটি ভেরিয়েবল হ'ল টিউপল (স্টোরেজ, স্কোপ, প্রকার, ঠিকানা, মান):

storage     :   where is it stored, for example data, stack, heap...
scope       :   who can see us, for example global, local...
type        :   what is our type, for example int, int*...
address     :   where are we located
value       :   what is our value

স্থানীয় স্কোপ স্থানীয় অনুবাদ অনুবাদ ইউনিট (উত্স ফাইল), ফাংশন বা ব্লক যেখানে এটি সংজ্ঞায়িত উপর নির্ভর করে স্থানীয় হতে পারে। একের অধিক ফাংশনে ভেরিয়েবলটি দৃশ্যমান করতে, এটি অবশ্যই ডেটা বা বিএসএস অঞ্চলে থাকতে হবে (যথাক্রমে এটির সূচনা স্পষ্টভাবে নয় কি না তার উপর নির্ভর করে)। এরপরে এটি উত্স ফাইলের মধ্যে সমস্ত ফাংশন (গুলি) বা ফাংশন (গুলি) এর অনুসারে স্কোপযুক্ত।


21

ডেটা সঞ্চয় করার অবস্থান বাস্তবায়ন নির্ভর হবে।

তবে স্থির অর্থ "অভ্যন্তরীণ সংযোগ"। সুতরাং, চিহ্নটি সংকলন ইউনিটের অভ্যন্তরীণ (foo.c, বার.c) এবং সংকলন ইউনিটের বাইরে উল্লেখ করা যায় না। সুতরাং, কোনও নাম সংঘর্ষ হতে পারে।


কোন। স্ট্যাটিক কীওয়ার্ডের ওভারলোডিং অর্থ রয়েছে: এই জাতীয় ক্ষেত্রে স্ট্যাটিক হ'ল স্টোরেজ মডিফায়ার, লিঙ্কেজ মোডিফায়ার নয়।
ugasoft

4
উগাসোফট: ফাংশনের বাইরে স্ট্যাটিকগুলি লিঙ্কেজ মোডিফায়ার, ভিতরে স্টোরেজ মডিফায়ার থাকে যেখানে কোনও সংঘর্ষ শুরু হতে পারে না।
জেনে

12

"গ্লোবাল এবং স্ট্যাটিক" অঞ্চলে :)

সি ++ তে বেশ কয়েকটি মেমরি অঞ্চল রয়েছে:

  • গাদা
  • ফ্রি স্টোর
  • গাদা
  • গ্লোবাল ও স্ট্যাটিক
  • const

আপনার প্রশ্নের বিস্তারিত উত্তরের জন্য এখানে দেখুন :

নিম্নলিখিতটিতে একটি সি ++ প্রোগ্রামের প্রধান স্বতন্ত্র মেমরি ক্ষেত্রগুলির সংক্ষিপ্তসার রয়েছে। মনে রাখবেন যে কয়েকটি নাম (যেমন, "হিপ") খসড়া [মানক] তে উপস্থিত হয় না।

     Memory Area     Characteristics and Object Lifetimes
     --------------  ------------------------------------------------

     Const Data      The const data area stores string literals and
                     other data whose values are known at compile
                     time.  No objects of class type can exist in
                     this area.  All data in this area is available
                     during the entire lifetime of the program.

                     Further, all of this data is read-only, and the
                     results of trying to modify it are undefined.
                     This is in part because even the underlying
                     storage format is subject to arbitrary
                     optimization by the implementation.  For
                     example, a particular compiler may store string
                     literals in overlapping objects if it wants to.


     Stack           The stack stores automatic variables. Typically
                     allocation is much faster than for dynamic
                     storage (heap or free store) because a memory
                     allocation involves only pointer increment
                     rather than more complex management.  Objects
                     are constructed immediately after memory is
                     allocated and destroyed immediately before
                     memory is deallocated, so there is no
                     opportunity for programmers to directly
                     manipulate allocated but uninitialized stack
                     space (barring willful tampering using explicit
                     dtors and placement new).


     Free Store      The free store is one of the two dynamic memory
                     areas, allocated/freed by new/delete.  Object
                     lifetime can be less than the time the storage
                     is allocated; that is, free store objects can
                     have memory allocated without being immediately
                     initialized, and can be destroyed without the
                     memory being immediately deallocated.  During
                     the period when the storage is allocated but
                     outside the object's lifetime, the storage may
                     be accessed and manipulated through a void* but
                     none of the proto-object's nonstatic members or
                     member functions may be accessed, have their
                     addresses taken, or be otherwise manipulated.


     Heap            The heap is the other dynamic memory area,
                     allocated/freed by malloc/free and their
                     variants.  Note that while the default global
                     new and delete might be implemented in terms of
                     malloc and free by a particular compiler, the
                     heap is not the same as free store and memory
                     allocated in one area cannot be safely
                     deallocated in the other. Memory allocated from
                     the heap can be used for objects of class type
                     by placement-new construction and explicit
                     destruction.  If so used, the notes about free
                     store object lifetime apply similarly here.


     Global/Static   Global or static variables and objects have
                     their storage allocated at program startup, but
                     may not be initialized until after the program
                     has begun executing.  For instance, a static
                     variable in a function is initialized only the
                     first time program execution passes through its
                     definition.  The order of initialization of
                     global variables across translation units is not
                     defined, and special care is needed to manage
                     dependencies between global objects (including
                     class statics).  As always, uninitialized proto-
                     objects' storage may be accessed and manipulated
                     through a void* but no nonstatic members or
                     member functions may be used or referenced
                     outside the object's actual lifetime.

12

আমার বিশ্বাস নেই যে সেখানে সংঘর্ষ হবে। ফাইল স্তরে স্থির ব্যবহার (বাইরের ফাংশন) বর্তমান সংকলন ইউনিট (ফাইল) এর স্থানীয় হিসাবে চলক চিহ্নিত করে। এটি বর্তমান ফাইলের বাইরে কখনও দৃশ্যমান হয় না তাই কখনও কখনও কোনও নাম থাকতে হবে না যা বাহ্যিকভাবে ব্যবহার করা যেতে পারে।

কোনও ফাংশনের অভ্যন্তরে স্থির ব্যবহার পৃথক - ভেরিয়েবলটি কেবলমাত্র ফাংশনটিতে দৃশ্যমান হয় (স্থির থাকুক বা না থাকুক), কেবলমাত্র এটির মান সেই ফাংশনের কলগুলিতে সংরক্ষিত থাকে।

কার্যত, স্থিতিশীল এটি যেখানে রয়েছে তার উপর নির্ভর করে দুটি পৃথক কাজ করে। তবে উভয় ক্ষেত্রেই ভেরিয়েবলের দৃশ্যমানতা এমনভাবে সীমাবদ্ধ থাকে যাতে লিঙ্ক করার সময় আপনি সহজেই নামস্পেস সংঘর্ষ রোধ করতে পারেন।

এই বলে, আমি বিশ্বাস করি এটি DATAবিভাগে সংরক্ষণ করা হবে , যার শূন্য ব্যতীত অন্য মানগুলিতে সূচনা হওয়া ভেরিয়েবল রয়েছে have এটি অবশ্যই একটি বাস্তবায়ন বিশদ, মানক দ্বারা বাধ্যতামূলক কিছু নয় - এটি কেবল আচরণের বিষয়ে চিন্তা করে, কীভাবে জিনিসগুলি কভারের আওতায় আনা হয় তা নয়।


1
@ প্যাক্সিডিয়াবল: আপনি দুটি ধরণের স্থিতিশীল ভেরিয়েবল উল্লেখ করেছেন। এই নিবন্ধটি ( এন.ইউইকিপিডিয়া ডটকম / উইকি / ডেটা_সেটমেন্ট ) এর মধ্যে কোনটির উল্লেখ রয়েছে? ডেটা বিভাগে গ্লোবাল ভেরিয়েবলগুলিও রয়েছে (যা প্রকৃতির তুলনায় স্থির প্রকৃতির বিপরীত) So, how does a segment of memory (Data Segment) store variables that can be accessed from everywhere (global variables) and also those which have limited scope (file scope or function scope in case of static variables)?
লেজার

@ ই এসকে, দৃশ্যমানতার সাথে এটি করা যায়। সেগমেন্টে এমন কিছু জিনিস সঞ্চিত থাকতে পারে যা সংকলন ইউনিটের স্থানীয়, অন্যেরা যা সম্পূর্ণরূপে অ্যাক্সেসযোগ্য। একটি উদাহরণ: প্রতিটি কম-ইউনিট ডেটা বিভাগে ব্লক অবদানের কথা ভাবেন। এটি জানে যে সেই ব্লকটিতে সমস্ত কিছুই রয়েছে। এটি অন্য ব্লগের সেই সমস্ত জিনিসগুলির ঠিকানাও প্রকাশ করে যা এটি অন্যান্য সহ-ইউনিটগুলিতে অ্যাক্সেস পেতে চায়। লিঙ্কার লিঙ্ক সময়ে এই ঠিকানাগুলি সমাধান করতে পারে।
প্যাক্সিডিয়াবলো

11

কীভাবে এটি নিজের সাথে সন্ধান করবেন objdump -Sr

কী চলছে তা বোঝার জন্য আপনাকে অবশ্যই লিঙ্কার স্থানান্তর বুঝতে হবে। আপনি যদি এটি কখনও স্পর্শ না করেন তবে প্রথমে এই পোস্টটি পড়ার বিষয়টি বিবেচনা করুন ।

একটি লিনাক্স x86-64 ELF উদাহরণ এটি বিশ্লেষণ করুন:

#include <stdio.h>

int f() {
    static int i = 1;
    i++;
    return i;
}

int main() {
    printf("%d\n", f());
    printf("%d\n", f());
    return 0;
}

এর সাথে সংকলন:

gcc -ggdb -c main.c

এর সাথে কোডটি ডিসম্পাইল করুন:

objdump -Sr main.o
  • -S মূল উত্সটি অন্তর্নির্মিত সহ কোডটি বিচ্ছিন্ন করে
  • -r স্থানান্তরের তথ্য প্রদর্শন করে

এর পচনটির ভিতরে fআমরা দেখতে পাই:

 static int i = 1;
 i++;
4:  8b 05 00 00 00 00       mov    0x0(%rip),%eax        # a <f+0xa>
        6: R_X86_64_PC32    .data-0x4

এবং .data-0x4বলে যে এটি .dataবিভাগের প্রথম বাইটে যাবে ।

-0x4নেই, কারণ আমরা অ্যাড্রেসিং ব্যবহার করছেন চেরা আপেক্ষিক, এইভাবে %ripনির্দেশ এবং R_X86_64_PC32

এটি প্রয়োজনীয় কারণ নিচের নির্দেশাবলীর দিকে আরআইপি নির্দেশ করে, যা 4 বাইট শুরু হয় 00 00 00 00যার পরে স্থানান্তরিত হবে। আমি এটি আরও বিস্তারিতভাবে এখানে ব্যাখ্যা করেছি: https://stackoverflow.com/a/30515926/895245

তারপরে, যদি আমরা উত্সটি পরিবর্তন i = 1করি এবং একই বিশ্লেষণ করি তবে আমরা এই সিদ্ধান্তে পৌঁছলাম:

  • static int i = 0 যায় .bss
  • static int i = 1 যায় .data


6

এটি আপনি যে প্ল্যাটফর্ম এবং সংকলকটি ব্যবহার করছেন তার উপর নির্ভর করে। কিছু সংকলক সরাসরি কোড বিভাগে সঞ্চয় করে। স্থিতিশীল ভেরিয়েবলগুলি সর্বদা কেবল বর্তমান অনুবাদ ইউনিটে অ্যাক্সেসযোগ্য এবং নামগুলি রফতানি হয় না কারণ নাম সংঘর্ষ কখনও ঘটে না।


5

সংকলন ইউনিটে ঘোষিত ডেটা .BSS বা files ফাইলগুলির আউটপুটটির .ডাটাতে যাবে। বিএসএস-এ সূচিত ডেটা, ডেটাতে আনইনিটালাইজড।

স্ট্যাটিক এবং গ্লোবাল ডেটাগুলির মধ্যে পার্থক্যটি ফাইলটিতে প্রতীক তথ্য অন্তর্ভুক্তির মাধ্যমে আসে। সংকলকগণ প্রতীক তথ্য অন্তর্ভুক্ত করতে থাকে তবে কেবল বৈশ্বিক তথ্য চিহ্নিত করে।

লিঙ্কার এই তথ্যটিকে সম্মান করে। স্ট্যাটিক ভেরিয়েবলের জন্য প্রতীক তথ্যটি বাতিল বা মাংগযুক্ত হয় যাতে স্থির ভেরিয়েবলগুলি এখনও কোনও উপায়ে (ডিবাগ বা প্রতীক বিকল্পগুলির সাথে) উল্লেখ করা যায়। কোনও ক্ষেত্রেই সংযোগকারী ইউনিটগুলি প্রভাবিত হতে পারে না কারণ লিঙ্কার আগে স্থানীয় রেফারেন্সগুলি সমাধান করে।


3

আমি এটি অজডাম্প এবং জিডিবি দিয়ে চেষ্টা করেছি, আমি যা পেয়েছি তার ফলাফল এখানে:

(gdb) disas fooTest
Dump of assembler code for function fooTest:
   0x000000000040052d <+0>: push   %rbp
   0x000000000040052e <+1>: mov    %rsp,%rbp
   0x0000000000400531 <+4>: mov    0x200b09(%rip),%eax        # 0x601040 <foo>
   0x0000000000400537 <+10>:    add    $0x1,%eax
   0x000000000040053a <+13>:    mov    %eax,0x200b00(%rip)        # 0x601040 <foo>
   0x0000000000400540 <+19>:    mov    0x200afe(%rip),%eax        # 0x601044 <bar.2180>
   0x0000000000400546 <+25>:    add    $0x1,%eax
   0x0000000000400549 <+28>:    mov    %eax,0x200af5(%rip)        # 0x601044 <bar.2180>
   0x000000000040054f <+34>:    mov    0x200aef(%rip),%edx        # 0x601044 <bar.2180>
   0x0000000000400555 <+40>:    mov    0x200ae5(%rip),%eax        # 0x601040 <foo>
   0x000000000040055b <+46>:    mov    %eax,%esi
   0x000000000040055d <+48>:    mov    $0x400654,%edi
   0x0000000000400562 <+53>:    mov    $0x0,%eax
   0x0000000000400567 <+58>:    callq  0x400410 <printf@plt>
   0x000000000040056c <+63>:    pop    %rbp
   0x000000000040056d <+64>:    retq   
End of assembler dump.

(gdb) disas barTest
Dump of assembler code for function barTest:
   0x000000000040056e <+0>: push   %rbp
   0x000000000040056f <+1>: mov    %rsp,%rbp
   0x0000000000400572 <+4>: mov    0x200ad0(%rip),%eax        # 0x601048 <foo>
   0x0000000000400578 <+10>:    add    $0x1,%eax
   0x000000000040057b <+13>:    mov    %eax,0x200ac7(%rip)        # 0x601048 <foo>
   0x0000000000400581 <+19>:    mov    0x200ac5(%rip),%eax        # 0x60104c <bar.2180>
   0x0000000000400587 <+25>:    add    $0x1,%eax
   0x000000000040058a <+28>:    mov    %eax,0x200abc(%rip)        # 0x60104c <bar.2180>
   0x0000000000400590 <+34>:    mov    0x200ab6(%rip),%edx        # 0x60104c <bar.2180>
   0x0000000000400596 <+40>:    mov    0x200aac(%rip),%eax        # 0x601048 <foo>
   0x000000000040059c <+46>:    mov    %eax,%esi
   0x000000000040059e <+48>:    mov    $0x40065c,%edi
   0x00000000004005a3 <+53>:    mov    $0x0,%eax
   0x00000000004005a8 <+58>:    callq  0x400410 <printf@plt>
   0x00000000004005ad <+63>:    pop    %rbp
   0x00000000004005ae <+64>:    retq   
End of assembler dump.

এখানে আপত্তিজনক ফলাফল

Disassembly of section .data:

0000000000601030 <__data_start>:
    ...

0000000000601038 <__dso_handle>:
    ...

0000000000601040 <foo>:
  601040:   01 00                   add    %eax,(%rax)
    ...

0000000000601044 <bar.2180>:
  601044:   02 00                   add    (%rax),%al
    ...

0000000000601048 <foo>:
  601048:   0a 00                   or     (%rax),%al
    ...

000000000060104c <bar.2180>:
  60104c:   14 00                   adc    $0x0,%al

সুতরাং, এটি বলার জন্য, আপনার চারটি ভেরিয়েবল একই বিভাগের ডেটা বিভাগ ইভেন্টে অবস্থিত, তবে বিভিন্ন অফসেট সহ।


এর চেয়েও অনেক কিছু আছে। এমনকি বিদ্যমান উত্তরগুলি সম্পূর্ণ নয়। কেবল অন্য কিছু উল্লেখ করার জন্য: স্থানীয়দের থ্রেড করুন।
অ্যাড্রিয়ানো রেপিটি

2

পূর্বে উল্লিখিত হিসাবে ডেটা বিভাগ বা কোড বিভাগে স্ট্যাটিক পরিবর্তনশীল।
আপনি নিশ্চিত হতে পারেন যে এটি স্ট্যাক বা হিপগুলিতে বরাদ্দ দেওয়া হবে না।
সংঘর্ষের ঝুঁকি নেই কারণ staticকীওয়ার্ডটি ভেরিয়েবলের ক্ষেত্রকে ফাইল বা ফাংশন হিসাবে সংজ্ঞায়িত করে, সংঘর্ষের ক্ষেত্রে আপনাকে সম্পর্কে সতর্ক করার জন্য একটি সংকলক / লিঙ্কার রয়েছে।
একটি দুর্দান্ত উদাহরণ


2

ঠিক আছে এই প্রশ্নটি বেশ পুরানো, তবে যেহেতু কেউ কোনও দরকারী তথ্য দেখায় না: প্রতীক টেবিলের মধ্যে একই নামে স্থিতিশীল ভেরিয়েবলের স্টোরটি ব্যাখ্যা করে পোস্টটি দেখুন 'মহিট 12379': http://www.geekinterview.com/question_details/ 24745


1

উত্তরটি সংকলকের উপর খুব ভালভাবে নির্ভর করতে পারে, তাই আপনি সম্ভবত আপনার প্রশ্নটি সম্পাদনা করতে চান (আমি বলতে চাইছি, এমনকি বিভাগগুলির ধারণাও আইএসও সি বা আইএসও সি ++ দ্বারা বাধ্যতামূলক নয়)। উদাহরণস্বরূপ, উইন্ডোজ একটি এক্সিকিউটেবল প্রতীক নাম বহন করে না। একটি 'ফু' অফসেট 0x100 হবে, অন্যটি সম্ভবত 0x2B0, এবং উভয় অনুবাদ ইউনিট থেকে কোড "তাদের" ফু জন্য অফসেটগুলি জেনে সংকলিত হয়েছে is


0

এগুলি উভয়ই স্বতন্ত্রভাবে সংরক্ষণ করা হবে, তবে আপনি যদি অন্য বিকাশকারীদের কাছে এটি স্পষ্ট করতে চান তবে আপনি সেগুলি নামের জায়গাগুলিতে গুটিয়ে রাখতে চাইতে পারেন।


-1

আপনি ইতোমধ্যে জেনে গেছেন যে এটি বিএস-এ সংরক্ষণ করা হয় (প্রতীক দ্বারা ব্লক শুরু) এটি অবিবেচনাযুক্ত ডেটা বিভাগ বা প্রাথমিক ডেটা বিভাগেও উল্লেখ করা হয়।

একটি সহজ উদাহরণ নিতে দিন

void main(void)
{
static int i;
}

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

void main(void)
{
static int i=10;
}

এবং অবশ্যই এটি 10 ​​দ্বারা আরম্ভ হয়েছিল সুতরাং এটি আরম্ভকৃত ডেটা বিভাগে যায়।

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