c - 'Sizeof'(একটি অ্যারে নির্দেশকারী একটি পয়েন্টার) কিভাবে খুঁজে?




স্ট্রাকচার প্রোগ্রামিং (9)

আপনি এই মত কিছু করতে পারেন:

int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;

প্রথম বন্ধ, এখানে কিছু কোড আছে:

int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

ptr নির্দেশ করে এমন অ্যারেটির আকার খুঁজে বের করার কোন উপায় আছে (কেবলমাত্র তার আকার দেওয়ার পরিবর্তে, যা 32-বিট সিস্টেমে চার বাইট)?


উত্তর হল, "না।"

কি সি প্রোগ্রামাররা কোথাও অ্যারে আকার সংরক্ষণ করুন। এটি একটি কাঠামোর অংশ হতে পারে, অথবা প্রোগ্রামার অ্যারের শুরু হওয়ার পূর্বে একটি দৈর্ঘ্য মান সঞ্চয় করার জন্য অনুরোধের চেয়ে একটি বিট এবং malloc () বেশি মেমরি প্রতারণা করতে পারে।


এই সমস্যাটির সমাধান আমার অ্যারের দৈর্ঘ্যটি অ্যারে সম্পর্কে একটি মেটা-তথ্য হিসাবে অ্যারেতে সংরক্ষণ করতে হয়।

#include <stdio.h>
#include <stdlib.h>

struct Array
{
    int length;

    double *array;
};

typedef struct Array Array;

Array* NewArray(int length)
{
    /* Allocate the memory for the struct Array */
    Array *newArray = (Array*) malloc(sizeof(Array));

    /* Insert only non-negative length's*/
    newArray->length = (length > 0) ? length : 0;

    newArray->array = (double*) malloc(length*sizeof(double));

    return newArray;
}

void SetArray(Array *structure,int length,double* array)
{
    structure->length = length;
    structure->array = array;
}

void PrintArray(Array *structure)
{       
    if(structure->length > 0)
    {
        int i;
        printf("length: %d\n", structure->length);
        for (i = 0; i < structure->length; i++)
            printf("%g\n", structure->array[i]);
    }
    else
        printf("Empty Array. Length 0\n");
}

int main()
{
    int i;
    Array *negativeTest, *days = NewArray(5);

    double moreDays[] = {1,2,3,4,5,6,7,8,9,10};

    for (i = 0; i < days->length; i++)
        days->array[i] = i+1;

    PrintArray(days);

    SetArray(days,10,moreDays);

    PrintArray(days);

    negativeTest = NewArray(-5);

    PrintArray(negativeTest);

    return 0;
}

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


কোন জাদু সমাধান নেই। সি একটি প্রতিফলিত ভাষা নয়। বস্তু স্বয়ংক্রিয়ভাবে তারা কি জানেন না।

কিন্তু আপনার অনেক পছন্দ আছে:

  1. অবশ্যই, একটি পরামিতি যোগ করুন
  2. একটি ম্যাক্রোতে কল মোড়ানো এবং স্বয়ংক্রিয়ভাবে একটি প্যারামিটার যুক্ত করুন
  3. আরো জটিল বস্তু ব্যবহার করুন। একটি গঠন সংজ্ঞায়িত করুন যা গতিশীল অ্যারে এবং অ্যারের আকার ধারণ করে। তারপর, কাঠামো ঠিকানা পাস।

না, অ্যারে ptr আকার নির্দেশ করতে আপনি sizeof(ptr) ব্যবহার করতে পারবেন না।

অতিরিক্ত পরিমাণে দৈর্ঘ্য সংরক্ষণ করতে চান তবে অতিরিক্ত মেমরি বরাদ্দ করা (অ্যারের আকারের চেয়ে বেশি) সহায়ক হবে।


না, তুমি পারবে না। কম্পাইলার পয়েন্টার নির্দেশ করছে কি জানেন না। কৌশলগুলি রয়েছে, যেমন অ্যারেটি একটি জ্ঞাত আউট অফ ব্যান্ড মানের সাথে শেষ করে এবং তারপরে সেই মান পর্যন্ত আকার গণনা করে, কিন্তু এটি sizeof ব্যবহার করে না।

অন্য কৌশলটি Zan দ্বারা উল্লেখ করা হয়, যা কোথাও আকারে টানতে হয়। উদাহরণস্বরূপ, যদি আপনি অ্যারেকে অস্থায়ীভাবে বরাদ্দ করছেন, আপনার প্রয়োজনের চেয়ে একটি বৃহত্তর একটি ব্লক বরাদ্দ করুন, প্রথম int তে আকারটি টানুন এবং অ্যারেতে পয়েন্টার হিসাবে পিটার + 1 ফেরত দিন। আপনি আকার প্রয়োজন হলে, স্ট্যাশ মান এ পয়েন্টার এবং peek হ্রাস। শুধু শুরু থেকে শুরু করে সম্পূর্ণ ব্লকটি মুক্ত করতে ভুলবেন না, কেবলমাত্র অ্যারের নয়।


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

/* http://.com/questions/492384/how-to-find-the-sizeof-a-pointer-pointing-to-an-array */
#include <stdio.h>
/* the following function will produce the warning:
 * ‘sizeof’ on array function parameter ‘a’ will
 * return size of ‘int *’ [-Wsizeof-array-argument]
 */
void foo( int a[] )
{
    printf( "%lu\n", sizeof a );
}
/* so we have to implement something else one possible
 * idea is to use the NULL pointer as a control value
 * the same way '\0' is used in strings but this way
 * the pointer passed to a function should address pointers
 * so the actual implementation of an array type will
 * be a pointer to pointer
 */
typedef char * type_t; /* line 18 */
typedef type_t ** array_t;
/*
 *    -- --
 *   -**-**-
 *   -$$$$$-
 *    -999-
 *     -^-
 *      -
 */
int main( void )
{
    array_t initialize( int, ... );
    /* initialize an array with four values "foo", "bar", "baz", "foobar"
     * if one wants to use integers rather than strings than in the typedef
     * declaration at line 18 the char * type should be changed with int
     * and in the format used for printing the array values 
     * at line 45 and 51 "%s" should be changed with "%i"
     */
    array_t array = initialize( 4, "foo", "bar", "baz", "foobar" );

    int size( array_t );
    /* print array size */
    printf( "size %i:\n", size( array ));

    void aprint( char *, array_t );
    /* print array values */
    aprint( "%s\n", array ); /* line 45 */

    type_t getval( array_t, int );
    /* print an indexed value */
    int i = 2;
    type_t val = getval( array, i );
    printf( "%i: %s\n", i, val ); /* line 51 */

    void delete( array_t );
    /* free some space */
    delete( array );

    return 0;
}
/* the output of the program should be:
 * size 4:
 * foo
 * bar
 * baz
 * foobar
 * 2: baz
 */
#include <stdarg.h>
#include <stdlib.h>
array_t initialize( int n, ... )
{
    /* here we store the array values */
    type_t *v = (type_t *) malloc( sizeof( type_t ) * n );
    va_list ap;
    va_start( ap, n );
    int j;
    for ( j = 0; j < n; j++ )
        v[j] = va_arg( ap, type_t );
    va_end( ap );
    /* the actual array will hold the addresses of those
     * values plus a NULL pointer
     */
    array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 ));
    a[n] = NULL;
    for ( j = 0; j < n; j++ )
        a[j] = v + j;
    return a;
}
int size( array_t a )
{
    int n = 0;
    while ( *a++ != NULL )
        n++;
    return n;
}
void aprint( char *fmt, array_t a )
{
    while ( *a != NULL )
        printf( fmt, **a++ );   
}
type_t getval( array_t a, int i )
{
    return *a[i];
}
void delete( array_t a )
{
    free( *a );
    free( a );
}
/* край */

Sizeof () ব্যবহার না করে সি ++ টেমপ্লেটগুলির সাথে একটি পরিচ্ছন্ন সমাধান রয়েছে। নিম্নলিখিত getSize () ফাংশন কোন স্ট্যাটিক অ্যারের আকার প্রদান করে:

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

এখানে foo_t কাঠামোর সাথে একটি উদাহরণ রয়েছে:

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

struct foo_t {
    int ball;
};

int main()
{
    foo_t foos3[] = {{1},{2},{3}};
    foo_t foos5[] = {{1},{2},{3},{4},{5}};
    printf("%u\n", getSize(foos3));
    printf("%u\n", getSize(foos5));

    return 0;
}

আউটপুট:

3
5

int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

দিনের আকার [] ২0 টি যা উপাদানগুলির কোনও * এর আকারের ডাটা প্রকারের নয়। পয়েন্টার আকার 4 যদিও এটা নির্দেশ করা হয় কোন ব্যাপার। কারণ একটি পয়েন্টার এটির ঠিকানা সংরক্ষণ করে অন্য উপাদানটিকে নির্দেশ করে।





sizeof