একই ভেক্টরের দুটি উল্লেখ কেন ভেক্টরের প্রতিটি উপাদানগুলির জন্য আলাদা মেমরি ঠিকানা দেয়?


9

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

> library(lobstr)
>
> x <- c(1500,2400,8800)
> y <- x
> ### So the following two lines must return the same memory address
> obj_addr(x)
[1] "0xb23bc50"
> obj_addr(y)
[1] "0xb23bc50"
> ### So as I expected, indeed both x and y point to the same memory 
> ### location: 0xb23bc50
>
>
>
> ### Now let's check that each element can be referenced by the same
> ### memory address either by using x or y
> x[1]
[1] 1500
> y[1]
[1] 1500
> obj_addr(x[1])
[1] "0xc194858"
> obj_addr(y[1])
[1] "0xc17db88"
> ### And here is exactly what I don't understand: x and y point 
> ### to the same memory address, so the same must be true for 
> ### x[1] and y[1]. So how come I obtain two different memory
> ### addresses for the same element of the same vector?
>
>
>
> x[2]
[1] 2400
> y[2]
[1] 2400
> obj_addr(x[2])
[1] "0xc15eca0"
> obj_addr(y[2])
[1] "0xc145d30"
> ### Same problem!
>
>
>
> x[3]
[1] 8800
> y[3]
[1] 8800
> obj_addr(x[3])
[1] "0xc10e9b0"
> obj_addr(y[3])
[1] "0xc0f78e8"
> ### Again the same problem: different memory addresses

আপনি আমাকে বলতে পারেন যে আমার ভুলটি কোথায় এবং আমি এই সমস্যায় কী ভুল বুঝেছি?


1
আমি আর জানি না তবে অন্যান্য ভাষায় আপনার মান এবং রেফারেন্স প্রকার রয়েছে। যদি পূর্ণসংখ্যা সি ++ বা সি # এর মতো মান টাইপ হয় তবে যে কোনও অ্যাসাইনমেন্ট নতুন পূর্ণসংখ্যা তৈরি করবে। সুতরাং প্রতিটি পূর্ণসংখ্যার নিজস্ব ঠিকানা থাকবে।
হোস্টেল

1
প্রকৃতপক্ষে, obj_addr(x[1])দু'বার দৌড়াতেও আপনাকে আলাদা ফলাফল দেওয়া উচিত, কারণ প্রতিটি নতুন পূর্ণসংখ্যার নিজস্ব ঠিকানা থাকবে।
বাস

@ বাস আমি আপনার যা যা উল্লেখ করেছি তা পরীক্ষা করেছিলাম, এটি হ'ল ধারাবাহিকভাবে ob_addr (x [1]) চালানো, এবং প্রকৃতপক্ষে এটি করার পরে আর প্রতিবারই আলাদা ফলাফল (ভিন্ন মেমরি ঠিকানা) দেয়। তবে আমি বুঝতে পারি না কেন, কারণ আমার কাছে যেমন মনে হয় আমি কোনও কিছু বরাদ্দ করি না, তাই আমি একটি নতুন অবজেক্ট তৈরি করি না (যার জন্য স্পষ্টতই একটি নতুন ঠিকানা থাকবে কারণ বস্তুগুলি আর-তে অবিচ্ছেদ্য)। আমার জন্য ob_addr (x [1]) এর অর্থ হ'ল আমি ইতিমধ্যে একটি বিদ্যমান অবজেক্টটি পড়ছি।
ব্যবহারকারী 17911

উত্তর:


5

যে কোনও আর অবজেক্টটি হ'ল সি (পয়েন্টার-কল SEXP- একটি) "মাল্টি-অবজেক্ট" ( struct)। এর মধ্যে lengthআর অবজেক্ট সম্পর্কে তথ্য (যেটি পরিচালনা করতে হবে, উদাহরণস্বরূপ , কোনও সংখ্যার রেফারেন্সের সংখ্যা- এবং কখন কোনও বস্তুর অনুলিপি করতে হবে তা জানতে হবে) এবং এছাড়াও, আমাদের যে অ্যাক্সেস রয়েছে সেই আর অবজেক্টের আসল ডেটা রয়েছে includes

lobstr::obj_addr, সম্ভবতঃ, একটি SEXPপয়েন্টের মেমরি ঠিকানাটি প্রদান করে। মেমরির সেই অংশটিতে আর অবজেক্টের তথ্য এবং ডেটা উভয়ই থাকে । আর পরিবেশের মধ্যে থেকে আমরা প্রতিটি আর অবজেক্টের প্রকৃত ডেটার মেমরির (পয়েন্টার) অ্যাক্সেস করার প্রয়োজন / করতে পারি না।

তার উত্তরে আদম নোট হিসাবে, ফাংশন [ কপি ডেটার n তম উপাদান একটি নতুন সি বস্তু সি বস্তুর অন্তর্ভুক্ত এবং তার ফেরৎ SEXPআর পয়েন্টার প্রতিবার [বলা একটি নতুন সি বস্তুর আর করার জন্য তৈরি করা এবং ফিরিয়ে দেওয়া হয় হয়

আমরা আর এর মাধ্যমে আমাদের অবজেক্টের আসল তথ্যের প্রতিটি উপাদানটির মেমরি ঠিকানাটি অ্যাক্সেস করতে পারি না But তবে কিছুটা খেলে আমরা সি এপি ব্যবহার করে সংশ্লিষ্ট ঠিকানাগুলি সনাক্ত করতে পারি:

ঠিকানাগুলি পেতে একটি ফাংশন:

ff = inline::cfunction(sig = c(x = "integer"), body = '
             Rprintf("SEXP @ %p\\n", x);

             Rprintf("first element of SEXP actual data @ %p\\n", INTEGER(x));

             for(int i = 0; i < LENGTH(x); i++) 
                 Rprintf("<%d> @ %p\\n", INTEGER(x)[i], INTEGER(x) + i);

             return(R_NilValue);
     ')

এবং আমাদের ডেটা প্রয়োগ করা:

x = c(1500L, 2400L, 8800L)  #converted to "integer" for convenience
y = x

lobstr::obj_addr(x)
#[1] "0x1d1c0598"
lobstr::obj_addr(y)
#[1] "0x1d1c0598"

ff(x)
#SEXP @ 0x1d1c0598
#first element of SEXP actual data @ 0x1d1c05c8
#<1500> @ 0x1d1c05c8
#<2400> @ 0x1d1c05cc
#<8800> @ 0x1d1c05d0
#NULL
ff(y)
#SEXP @ 0x1d1c0598
#first element of SEXP actual data @ 0x1d1c05c8
#<1500> @ 0x1d1c05c8
#<2400> @ 0x1d1c05cc
#<8800> @ 0x1d1c05d0
#NULL

আমাদের অবজেক্টের ডেটা উপাদানগুলির মধ্যে ক্রমাগত মেমরির পার্থক্য intটাইপের আকারের সমান :

diff(c(strtoi("0x1d1c05c8", 16), 
       strtoi("0x1d1c05cc", 16), 
       strtoi("0x1d1c05d0", 16)))
#[1] 4 4

[ফাংশন ব্যবহার :

ff(x[1])
#SEXP @ 0x22998358
#first element of SEXP actual data @ 0x22998388
#<1500> @ 0x22998388
#NULL
ff(x[1])
#SEXP @ 0x22998438
#first element of SEXP actual data @ 0x22998468
#<1500> @ 0x22998468
#NULL

এটি প্রয়োজনীয় বিস্তৃত জবাবের চেয়ে বেশি হতে পারে এবং প্রকৃত প্রযুক্তিগতগুলিতে সরল, তবে, আশা করা যায়, আরও পরিষ্কার "বড়" চিত্র সরবরাহ করে।


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

3

এটি দেখার জন্য এটি একটি উপায়। আমি নিশ্চিত যে আরও একটি প্রযুক্তিগত ভিউ আছে। মনে রাখবেন যে আর এর মধ্যে প্রায় সব কিছুই একটি ফাংশন। এর মধ্যে রয়েছে এক্সট্রাক্ট ফাংশন [,। এখানে একটি সমতুল্য বিবৃতি x[1]:

> `[`(x, 1)
[1] 1500

সুতরাং আপনি যা করছেন একটি ফাংশন চলছে যা একটি মান দেয় (চেক আউট ?Extract)। মানটি একটি পূর্ণসংখ্যা। যখন আপনি চালাতে obj_addr(x[1]), এটা ফাংশন নির্ণয় করা হয় x[1]এবং তারপর আপনি দান obj_addr()যে ফাংশন ফেরতের না অ্যারের প্রথম উপাদান যে আপনি উভয় বাধ্য করছে তার ঠিকানার সাথে xএবং y


আপনার সহায়তার জন্য এবং আমার সমস্যার প্রতি আপনার মনোযোগের জন্য আপনাকে অনেক ধন্যবাদ। প্রকৃতপক্ষে এটি আমি জানতাম না, এটি হ'ল "এক্সট্র্যাক্ট" দ্বারা একটি মান পুনরুদ্ধার করা আসলেই একটি নতুন অবজেক্ট তৈরি করে। যেমনটি আমি বলেছিলাম যে আমি সত্যিই আর এর একটি শিক্ষানবিস! আপনার সময় এবং আপনার বর্ণনার জন্য আপনাকে অনেক ধন্যবাদ।
ব্যবহারকারী 17911
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.