স্টার্ডআপ () - এটি সিতে কী করে?


302

strdup()সি এর কাজটির উদ্দেশ্য কী ?


44
এছাড়াও স্টার্ডুপ () (জিএনইউ সি লাইব্রেরিতে) রয়েছে, একটি দুর্দান্ত ফাংশন যা স্টার্ডআপ () এর মতো, তবে স্ট্যাকের উপর মেমরি বরাদ্দ করে। আপনার প্রোগ্রামটির স্পষ্টভাবে মেমরিটি মুক্ত করার দরকার নেই যেমন স্টার্ডআপ () এর ক্ষেত্রে, আপনি যখন স্টারডুপাকে () বলা হয়েছিল সেই ফাংশনটি থেকে বেরিয়ে আসলে এটি স্বয়ংক্রিয়ভাবে মুক্তি পাবে
dmityugov

11
strdupaবিপজ্জনক এবং এটি ব্যবহার করা উচিত নয় যতক্ষণ না আপনি ইতিমধ্যে নির্ধারণ করেছেন যে strlenএটি খুব ছোট। তবে আপনি কেবল স্ট্যাকের উপর স্থির আকারের অ্যারে ব্যবহার করতে পারেন।
আর .. গিথহাব বন্ধ করুন ICE

4
@ স্ল্যাকার গুগল অনুবাদ সহায়ক হচ্ছে না ... পোলিশ ভাষায় strdup/ এর strdupaঅর্থ কী ?
হানিফমুবারক


এখানে strdup এবং strcpy মধ্যে পার্থক্য stackoverflow.com/questions/14020380/strcpy-vs-strdup
শিব প্রকাশ

উত্তর:


372

হুবহু কী মনে হচ্ছে, ধরে নিই যে আপনি সংক্ষেপে যেভাবে সি এবং ইউএনএক্স শব্দ ব্যবহার করেছেন তা ব্যবহার করছেন, এটি স্ট্রিকে নকল করে :-)

এটি আসলে আইএসও সি স্ট্যান্ডার্ড নিজেই (ক) (এটি একটি পসিক্স বিষয়) এর অংশ নয়, এটি কার্যকরভাবে নিম্নলিখিত কোডের মতোই করছে:

char *strdup(const char *src) {
    char *dst = malloc(strlen (src) + 1);  // Space for length plus nul
    if (dst == NULL) return NULL;          // No memory
    strcpy(dst, src);                      // Copy the characters
    return dst;                            // Return the new string
}

অন্য কথায়:

  1. এটি পুরানো স্ট্রিং ধরে রাখতে পর্যাপ্ত মেমরি বরাদ্দ করার চেষ্টা করে (স্ট্রিংয়ের শেষে চিহ্নিত করতে একটি '\ 0' অক্ষর)।

  2. যদি বরাদ্দটি ব্যর্থ হয় তবে তা সেট errnoহয়ে যায় ENOMEMএবং NULLসঙ্গে সঙ্গে ফিরে আসে returns সেটিং errnoথেকে ENOMEMকিছু mallocPOSIX মধ্যে আছে তাই আমরা স্পষ্টভাবে আমাদের এটা করতে প্রয়োজন হবে না strdup। আপনি যদি পসিক্স অনুগত না হন , আইএসও সি আসলে এর অস্তিত্বের আদেশ দেয় না ENOMEMতাই আমি এটিকে এখানে (বি) অন্তর্ভুক্ত করি নি ।

  3. অন্যথায় বরাদ্দ কাজ করেছিল তাই আমরা পুরানো স্ট্রিংটিকে নতুন স্ট্রিংয়ে (গ) অনুলিপি করে নতুন ঠিকানাটি (যা কলারটি কিছুটা সময় মুক্ত করার জন্য দায়ী ) ফিরিয়ে দেয়।

মাথায় রাখুন যে ধারণা সংজ্ঞা। যে কোনও লাইব্রেরি লেখক তাদের বেতনের মূল্যবান নির্দিষ্ট প্রসেসরটি লক্ষ্য করে প্রচুর অপ্টিমাইজড কোড সরবরাহ করেছেন।


(ক) তবে, শুরু হওয়া ফাংশন strএবং একটি ছোট কেস লেটার ভবিষ্যতের দিকনির্দেশের জন্য মান দ্বারা সংরক্ষিত। থেকে C11 7.1.3 Reserved identifiers:

প্রতিটি শিরোনাম তার সম্পর্কিত সাব-ক্লজ-এ তালিকাবদ্ধ সমস্ত সনাক্তকারীকে ঘোষণা করে বা সংজ্ঞায়িত করে এবং * এটি সম্পর্কিত ভবিষ্যতের গ্রন্থাগারের দিকনির্দেশের উপ-ধারাটিতে তালিকাভুক্ত সনাক্তকারীকে বিকল্পভাবে ঘোষণা বা সংজ্ঞা দেয়। **

এর জন্য ভবিষ্যতের দিকনির্দেশগুলি string.hপাওয়া যাবে C11 7.31.13 String handling <string.h>:

ফাংশন নাম যে দিয়ে শুরু str, memঅথবা wcsএবং ছোট হাতের অক্ষর মধ্যে ঘোষণা যোগ করা যেতে পারে <string.h>হেডার।

সুতরাং আপনি যদি নিরাপদে থাকতে চান তবে আপনার সম্ভবত এটি অন্য কিছু বলা উচিত।


(খ) পরিবর্তনটি মূলত এর if (d == NULL) return NULL;সাথে প্রতিস্থাপন করবে :

if (d == NULL) {
    errno = ENOMEM;
    return NULL;
}

(গ) নোট করুন যে আমি এটির strcpyজন্য ব্যবহার করেছি যেহেতু এটি স্পষ্টভাবে উদ্দেশ্যটি দেখায়। কিছু বাস্তবায়নে এটি দ্রুততর হতে পারে (যেহেতু আপনি ইতিমধ্যে দৈর্ঘ্যটি জানেন) memcpyকারণ তারা বড় অংশগুলিতে বা সমান্তরালভাবে ডেটা স্থানান্তর করতে পারে। অথবা এটি নাও পারে :-) অপ্টিমাইজেশন মন্ত্র # 1: "পরিমাপ, অনুমান করবেন না"।

যাই হোক না কেন, আপনি যদি সেই পথে যাওয়ার সিদ্ধান্ত নেন, আপনি এমন কিছু করবেন:

char *strdup(const char *src) {
    size_t len = strlen(src) + 1;       // String plus '\0'
    char *dst = malloc(len);            // Allocate space
    if (dst == NULL) return NULL;       // No memory
    memcpy (dst, src, len);             // Copy the block
    return dst;                         // Return the new string
}

8
এটি লক্ষণীয় যে প্যাক্সের 'নমুনা বাস্তবায়নের সূত্রে স্টার্ডআপ (এনইউএল) অপরিজ্ঞাত এবং এমন কোনও কিছু নয় যা আপনি কোনও অনুমানযোগ্য আচরণের আশা করতে পারেন।
বিনোদন

2
এছাড়াও, আমি মনে করি malloc () errno সেট করবে, সুতরাং আপনার নিজের এটি সেট করা উচিত নয়। আমি মনে করি.
ক্রিস লুটজ

5
@ অ্যালকোট, strdupসেই পরিস্থিতিতে আপনি স্ট্রিং কপির জন্য বরাদ্দ হ্যাপ মেমরি চান। অন্যথায় আপনাকে এটি নিজেই করতে হবে। যদি আপনি ইতিমধ্যে যদি আছে একটি বড় যথেষ্ট বাফার (malloc'ed বা অন্যভাবে), হ্যাঁ, ব্যবহার strcpy
paxdiablo

2
@ অ্যাক্টিটার্যান্ট: যদি, স্ট্যান্ডার্ড অনুসারে, আপনি আইএসও স্ট্যান্ডার্ডকে (আসল সি স্ট্যান্ডার্ড) বোঝায়, না, এটি এর অংশ নয়। এটি পসিক্স স্ট্যান্ডার্ডের একটি অংশ। যাইহোক, প্রচুর সি বাস্তবায়ন রয়েছে যা এটি প্রদান করে, আইএসও সি-র একটি সরকারী অংশ না হওয়া সত্ত্বেও, যদিও তারা তা না করে, এই উত্তরটির পাঁচটি-লাইনার পর্যাপ্ত পরিমাণের চেয়ে বেশি হওয়া উচিত।
paxdiablo

2
গুড পয়েন্ট, @chux, আইএসও { EDOM, EILSEQ, ERANGE }প্রয়োজনীয় ত্রুটি কোড হিসাবে আদেশ দেয় । এর জন্য অ্যাকাউন্টে উত্তর আপডেট করেছেন।
paxdiablo

86
char * strdup(const char * s)
{
  size_t len = 1+strlen(s);
  char *p = malloc(len);

  return p ? memcpy(p, s, len) : NULL;
}

হয়তো কোড একটি বিট সঙ্গে চেয়ে দ্রুত strcpy()হিসাবে \0CHAR (এটা ইতিমধ্যেই সঙ্গে ছিল আবার অনুসন্ধান করা হবে না strlen())।


ধন্যবাদ। আমার ব্যক্তিগত বাস্তবায়নে আমি এটিকে আরও "খারাপ" করে তুলেছি। return memcpy(malloc(len), s, len);আমি NULLবরাদ্দ ব্যর্থতার চেয়ে বরাদ্দ ক্র্যাশ পছন্দ ।
প্যাট্রিক Schlüter

3
@ থ্রিস্টোপিয়া ডেরেফারেন্সিং NULLক্র্যাশ করতে হবে না; এটি অপরিবর্তিত যদি আপনি নিশ্চিত হয়ে যেতে চান যে এটি ক্র্যাশ হয়ে গেছে, তবে এমন একটি লিখুন emallocযা কল abortব্যর্থ হওয়ার আহ্বান জানায়।
ডেভ

আমি এটি জানি, তবে আমার বাস্তবায়ন কেবল সোলারিস বা লিনাক্সে (অ্যাপের প্রকৃতির দ্বারা) চালানোর গ্যারান্টিযুক্ত।
প্যাট্রিক Schlüter

@ ত্রিস্টোপিয়া: সবচেয়ে ভাল জিনিস করার অভ্যাসে থাকা ভাল। emallocসোলারিস বা লিনাক্সে প্রয়োজনীয় না হলেও ব্যবহার করার অভ্যাস করুন যাতে আপনি ভবিষ্যতে অন্য প্ল্যাটফর্মগুলিতে কোড লেখার সময় এটি ব্যবহার করবেন।
আর্টঅফ ওয়ারফেয়ার

51

অন্য উত্তরগুলির পুনরাবৃত্তি করার কোনও অর্থ নেই, তবে দয়া করে নোট করুন যে strdup()এটি কোনও সি মানের বিবেচনা না করে এটি সি দৃষ্টিকোণ থেকে যা কিছু করতে পারে তা করতে পারে। এটি POSIX.1-2-2001 দ্বারা সংজ্ঞায়িত করা হয়েছে।


4
কি strdup()পোর্টেবল? না, পসিক্স-বিহীন পরিবেশে উপলব্ধ নয় (যাইহোক তুচ্ছভাবে প্রয়োগযোগ্য)। তবে কোনও পসিক্স ফাংশন যে কোনও কিছু করতে পারে তা বলা বেশ প্যাডেন্টিক। পসিক্স হ'ল একটি স্ট্যান্ডার্ড যা সি এর মতোই ভাল এবং আরও জনপ্রিয়।
পিপি

2
@ ব্লুউমুন আমি মনে করি মূল বিষয়টি হ'ল একটি সি বাস্তবায়ন যা পসিক্সের সাথে কোনও সামঞ্জস্য দাবি না করে এখনও strdupএক্সটেনশন হিসাবে কোনও ফাংশন সরবরাহ করতে পারে । এই ধরনের বাস্তবায়নের ক্ষেত্রে, কোনও গ্যারান্টি নেই যে strdupএটি পসিক্স ফাংশনের মতোই আচরণ করে। আমি এ জাতীয় কোনও বাস্তবায়ন সম্পর্কে জানি না, তবে বৈধ অ-দূষিত প্রয়োগটি char *strdup(char *)historicতিহাসিক কারণে সরবরাহ করতে পারে এবং একটিতে পাস করার প্রচেষ্টা প্রত্যাখ্যান করে const char *

সি স্ট্যান্ডার্ড এবং পসিক্সের মধ্যে পার্থক্য কী? সি স্ট্যান্ডার্ড বলতে কী বোঝায়, এটি সি স্ট্যান্ডার্ড লাইব্রেরিতে বিদ্যমান নেই?
Koray Tugay

@ KorayTugay তারা পৃথক মান। এগুলি সম্পর্কযুক্ত হিসাবে বিবেচনা করা ভাল, যদি না আপনি জানেন যে কোনও নির্দিষ্ট সি ফাংশনের মানটি POSIX মানের সাথে খাপ খায় এবং আপনার সংকলক / গ্রন্থাগারটি সেই ফাংশনের মানকে মেনে চলে।
ম্যাথু পড়ুন

17

স্টার্ডআপ ম্যান থেকে :

strdup()ফাংশন একটি নতুন স্ট্রিং, যা স্ট্রিং দ্বারা প্রতি ইঙ্গিত অনুরূপ একটি পয়েন্টার ফিরে আসব s1। ফিরে পয়েন্টারটি পাস করা যেতে পারে free()। নতুন স্ট্রিং তৈরি করা না গেলে নাল পয়েন্টারটি ফেরত দেওয়া হয়।


4

strdup () শেষ অক্ষর '\ 0' সহ অক্ষর অ্যারে জন্য গতিশীল মেমরি বরাদ্দ করে এবং হিপ মেমরির ঠিকানা প্রদান করে:

char *strdup (const char *s)
{
    char *p = malloc (strlen (s) + 1);   // allocate memory
    if (p != NULL)
        strcpy (p,s);                    // copy string
    return p;                            // return the memory
}

সুতরাং, এটি যা করে তা হল আমাদের মেমরি বরাদ্দ না করে তার যুক্তি অনুসারে স্ট্রিংয়ের অনুরূপ আরও একটি স্ট্রিং দেয়। তবে আমাদের এখনও এটি মুক্ত করা দরকার later


3

এটা তোলে স্ট্রিং একটি চলমান দ্বারা পাস একটি সদৃশ অনুলিপি তোলে যদি malloc এবং strcpy স্ট্রিং গৃহীত। Malloc'ed বাফার কলারের কাছে চালানোর জন্য প্রয়োজন ফিরিয়ে দেওয়া হয়, অত বিনামূল্যে ফেরত মান উপর।


3

strdupএবং strndupPOSIX অনুবর্তী সিস্টেমগুলিতে হিসাবে সংজ্ঞায়িত করা হয়:

char *strdup(const char *str);
char *strndup(const char *str, size_t len);

Strdup () ফাংশন স্ট্রিং এর একটি কপি জন্য যথেষ্ট মেমরি বরাদ্দ str, এটা, অনুলিপি, এবং আয় একটি পয়েন্টার আছে।

পয়েন্টারটি পরবর্তী সময়ে ফাংশনের আর্গুমেন্ট হিসাবে ব্যবহৃত হতে পারে free

অপর্যাপ্ত মেমরি উপলব্ধ থাকলে, NULLফিরে আসে এবং errnoসেট করা হয় ENOMEM

Strndup () সর্বাধিক ফাংশন কপি lenস্ট্রিং থেকে অক্ষর strসবসময় কপি স্ট্রিং সসীম নাল।


1

এটি সর্বাধিক মূল্যবান জিনিসটি হ'ল আপনাকে নিজের জন্য মেমরি (স্থান এবং আকার) বরাদ্দ না করে প্রথমটিকে অনুরূপ আরেকটি স্ট্রিং দেয়। তবে, যেমনটি উল্লেখ করা হয়েছে, আপনাকে এখনও এটি মুক্ত করতে হবে (তবে এটির জন্য কোনও পরিমাণ গণনার প্রয়োজন নেই))


1

বিবৃতি:

strcpy(ptr2, ptr1);

এর সমতুল্য (সত্য যা পয়েন্টারগুলিকে পরিবর্তন করে তা বাদে):

while(*ptr2++ = *ptr1++);

যেখানে:

ptr2 = strdup(ptr1);

সমান:

ptr2 = malloc(strlen(ptr1) + 1);
if (ptr2 != NULL) strcpy(ptr2, ptr1);

সুতরাং, আপনি যদি অনুলিপিযুক্ত স্ট্রিংটি অন্য কোনও ফাংশনে (যেমন এটি হিপ বিভাগে তৈরি করা হয়) ব্যবহার করতে চান তবে আপনি ব্যবহার করতে পারেন strdup, অন্যথায় strcpyযথেষ্ট,


0

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


1
যুক্তিটির জন্য strdupস্ট্রিং ধ্রুবক হওয়া দরকার না, এটি অবশ্যই একটি সি স্ট্রিং, অর্থাত্ একটি নাল টার্মিনেটেড অ্যারে char
chqrlie
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.