স্ট্যান্ড :: স্ট্রিং :: সি_স্ট্রেল () আজীবন কী?


101

আমার একটি প্রোগ্রামে আমাকে কিছু লিগ্যাসি কোড দিয়ে ইন্টারফেস করতে হবে যা এর সাথে কাজ করে const char*

বলুন যে আমার কাছে এমন কাঠামো রয়েছে যা দেখতে দেখতে:

struct Foo
{
  const char* server;
  const char* name;
};

আমার উচ্চ-স্তরের অ্যাপ্লিকেশনটি কেবলমাত্র এর সাথেই কাজ করে std::string, তাই আমি পয়েন্টার std::string::c_str()ফিরে পেতে ব্যবহার করার কথা ভেবেছিলাম const char*

তবে জীবনকাল কী c_str()?

অপরিবর্তিত আচরণের মুখোমুখি না করে কি আমি এই জাতীয় কিছু করতে পারি?

{
  std::string server = "my_server";
  std::string name = "my_name";

  Foo foo;
  foo.server = server.c_str();
  foo.name = name.c_str();

  // We use foo
  use_foo(foo);

  // Foo is about to be destroyed, before name and server
}

বা আমার সাথে সাথে ফলাফলটি c_str()অন্য জায়গায় অনুলিপি করার কথা ?

ধন্যবাদ.


আমার সাথে ঘটেছিল যখন আমি কোনও ফাংশনে স্থানীয় স্ট্রিং সংজ্ঞায়িত করে ফিরে এসেছি .c_str()। আমি বুঝতে পারি না কেন মাঝে মাঝে আমি কেবল স্ট্রিংয়ের কিছু অংশ পাই, যতক্ষণ না বুঝেছি যে const char*চিরকাল বেঁচে নেই, তবে স্ট্রিংটি ধ্বংস না হওয়া অবধি
কিছু

উত্তর:


86

c_str()যদি ফলাফলের অবৈধ হয়ে std::stringধ্বংস করা হয় বা স্ট্রিং এর একটি অ-const সদস্য ফাংশন বলা হয় পারেন। সুতরাং, আপনার যদি এটি প্রায় রাখার প্রয়োজন হয় তবে আপনি এটির একটি অনুলিপি তৈরি করতে চাইবেন।

আপনার উদাহরণের ক্ষেত্রে, এটি প্রদর্শিত হয় যে ফলাফলগুলি c_str()নিরাপদে ব্যবহৃত হয়, কারণ স্ট্রিংগুলিতে থাকা অবস্থায় স্ট্রিংগুলি সংশোধিত হয় না। (তবে, আমরা জানি না those মানগুলির সাথে কী use_foo()বা কী ~Foo()করা যায়; তারা যদি অন্যত্র স্ট্রিংগুলি অনুলিপি করে, তবে তাদের উচিত একটি সত্য অনুলিপি করা , এবং কেবল charপয়েন্টারগুলি অনুলিপি করা উচিত নয় ))


c_str () পয়েন্টারটি অবৈধ হতে পারে যদি std :: স্ট্রিং অবজেক্টটি একটি স্বয়ংক্রিয় অবজেক্ট স্কোপের বাইরে চলে যায় বা থ্রেড তৈরির ফাংশনে কল করে।
গুরুম

আপনি দয়া করে ব্যাখ্যা করতে পারেন non-const member function of the string is called.?
ম্যাথিউ কুরিয়ান

4
একটি "নন-কনস্ট্যান্ড সদস্য ফাংশন" এমন কোনও সদস্য ফাংশন যা মূলশব্দটির সাথে চিহ্নিত নয় const। এই জাতীয় ফাংশন স্ট্রিংয়ের বিষয়বস্তুগুলিকে পরিবর্তন করতে পারে, সেক্ষেত্রে স্ট্রিংটির দ্বারা ফিরে আসা স্ট্রিংয়ের নাল-টার্মিনেটেড সংস্করণটির জন্য মেমরিটিকে পুনরায় স্থান দিতে হবে c_str()। উদাহরণস্বরূপ, size()এবং length()হয় const, তাই আপনি সেগুলি স্ট্রিং পরিবর্তন সম্পর্কে উদ্বেজক ছাড়া কল করতে পারেন, কিন্তু clear()নয় const
ক্রিস্টোফার জনসন

23

প্রযুক্তিগতভাবে আপনার কোড ঠিক আছে।

তবে আপনি এমনভাবে লিখেছেন যাতে কোডটি জানে না এমন কারও পক্ষে ব্রেক করা সহজ করে তোলে। C_str () এর জন্য কেবলমাত্র নিরাপদ ব্যবহার হ'ল আপনি যখন এটি কোনও ফাংশনের পরামিতি হিসাবে পাস করেন। অন্যথায় আপনি আপ আপ টু আপ রক্ষণাবেক্ষণ সমস্যা।

উদাহরণ 1:

{
  std::string server = "my_server";
  std::string name   = "my_name";

  Foo foo;
  foo.server = server.c_str();
  foo.name = name.c_str();

  //
  // Imagine this is a long function
  // Now a maintainer can easily come along and see name and server
  // and would never expect that these values need to be maintained as
  // const values so why not re-use them

  name += "Martin";
  // Oops now its broken.

  // We use foo
  use_foo(foo);

  // Foo is about to be destroyed, before name and server
}

সুতরাং রক্ষণাবেক্ষণের জন্য এটি সুস্পষ্ট করুন:

আরও ভাল সমাধান:

{
  // Now they can't be changed.
  std::string const server = "my_server";
  std::string const name   = "my_name";

  Foo foo;
  foo.server = server.c_str();
  foo.name = name.c_str();

  use_foo(foo);    
}

তবে আপনার যদি কনস্টিং স্ট্রিং থাকে তবে আপনার আসলে তাদের প্রয়োজন হয় না:

{
  char const* server = "my_server";
  char const* name   = "my_name";

  Foo foo;
  foo.server = server;
  foo.name   = name;

  use_foo(foo);
}

ঠিক আছে. কোনও কারণে আপনি এগুলি স্ট্রিং হিসাবে চান:
কেন কেবল সেগুলিতে সেগুলি ব্যবহার করবেন না:

{
  std::string server = "my_server";
  std::string name = "my_name";

  // guaranteed not to be modified now!!!     
  use_foo(Foo(server.c_str(), name.c_str());
}

7

সংশ্লিষ্ট stringঅবজেক্টের সাথে নিম্নলিখিতগুলির মধ্যে একটির না হওয়া পর্যন্ত এটি বৈধ :

  • বস্তু ধ্বংস হয়
  • অবজেক্টটি সংশোধিত হয়েছে

আপনার কোডে যদি না আপনি ঐ সংশোধন সাথে এসেছেন জরিমানা stringপর বস্তু c_str()গুলি অনুলিপি করছে fooকিন্তু আগে use_foo()বলা হয়।


4

C_str () এর রিটার্ন মান একই স্ট্রিংয়ের জন্য নন-কনস্ট্যান্ট সদস্য ফাংশনের পরবর্তী কল না হওয়া পর্যন্ত বৈধ


3

const char*থেকে প্রত্যাবর্তিতটি কেবল অবজেক্টে c_str()পরবর্তী নন-কনস্ট্যান্ট কল না হওয়া পর্যন্ত বৈধ std::stringstd::stringএক্ষেত্রে আপনি ভাল আছেন কারণ আপনার এখনও জীবদ্দশায় সুযোগ রয়েছে Fooএবং আপনি ফু ব্যবহারের সময় স্ট্রিং পরিবর্তন করতে এমন কোনও অপারেশন করছেন না।


2

যতক্ষণ না স্ট্রিংটি ধ্বংস হয় বা সংশোধিত হয় না ততক্ষণ c_str () ব্যবহার করা ঠিক আছে। যদি পূর্বে প্রত্যাবর্তিত c_str () ব্যবহার করে স্ট্রিংটি সংশোধন করা হয় তবে তা বাস্তবায়ন সংজ্ঞায়িত হয়।


2

সম্পূর্ণতার জন্য, এখানে cppreferences.com থেকে একটি রেফারেন্স এবং উদ্ধৃতি :

প্রাপ্ত পয়েন্টারটি c_str()দ্বারা অবৈধ হতে পারে:

  • কোনও স্ট্যান্ডার্ড লাইব্রেরি ফাংশনে স্ট্রিংটির অ-কনস্ট্যান্ড রেফারেন্স পাস করা, বা
  • নন-const সদস্য ফাংশন কল করা হচ্ছে string, ব্যতীত operator[], at(), front(), back(), begin(), rbegin(), end()এবং rend()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.