tags:

views:

155

answers:

2

Hello, I am finding it difficult to determine the length of the columns in a 2D unsigned short pointer array. I have done memory allocation correctly as far as I know. and can print them correctly.

plz see the following code segment:

int number_of_array_index_required_for_pointer_abc=3;
char A[3][16];


strcpy(A[0],"Hello");
strcpy(A[1],"World");
strcpy(A[2],"Tumanicko");


cout<<number_of_array_index_required_for_pointer_abc*sizeof(unsigned short)<<endl;
unsigned short ** pqr=(unsigned short **)malloc(number_of_array_index_required_for_pointer_abc*sizeof(unsigned short));




    for(int i=0;i<number_of_array_index_required_for_pointer_abc;i++)
    {

        int ajira = strlen(A[i])*sizeof(unsigned short);
        cout<<i<<" = "<<ajira<<endl;
        pqr[i]=(unsigned short *)malloc(ajira);
        cout<<"alocated pqr[i]= "<<sizeof pqr<<endl;


        int j=0;
        for(j=0;j<strlen(A[i]);j++)
        {
            pqr[i][j]=(unsigned short)A[i][j];

        }
        pqr[i][j]='\0';


    }


    for(int i=0;i<number_of_array_index_required_for_pointer_abc;i++)
    {

        //ln= (sizeof pqr[i])/(sizeof pqr[0]);

        //cout<<"Size of pqr["<<i<<"]= "<<ln<<endl;


         // I want to know the size of the columns i.e. pqr[i]'s length instead of finding '\0'

         for(int k=0;(char)pqr[i][k]!='\0';k++)
        cout<<(char)pqr[i][k];
        cout<<endl;

    }
A: 

You have a bug at this line:

pqr[i][j]='\0';

At this point j is equal to strlen(A[i]) - which is outside the bounds you setup for pqr:

int ajira = strlen(A[i])*sizeof(unsigned short);
pqr[i]=(unsigned short *)malloc(ajira);

pqr[i] goes from [0] to [strlen(A[i])-1] so writing to pqr[i][strlen(A[i])] overflows the array. The compiler won't pick up on this as you allocated the memory yourself.

The solution to that bug is to do malloc(ajira+sizeof(unsigned short))

Edited after comments

Mark Pim
`malloc(ajira+1)` is not enough: you need to add memory for an unsigned short and you're adding a single byte. Also, it's incorrect that `\0` will overwrite the next `unsigned short[]`, since each array is allocated separately. It will invoke undefined behavior though.
interjay
Btw, the current code is working ok. What you said is right but this line pqr[i][j]='\0' was written when I didn't get the length of the pqr[i], so i needed a '\0' flag to determine the size. So, with your suggested change I didn't get the size of the pqr[i] either.
What do you get instead then? Does it crash? Not compile? Return 0? Return a random amount? Return 1 more than the expected length?
Mark Pim
A: 

You're almost there. You have this loop:

for(int k=0;(char)pqr[i][k]!='\0';k++) ...

Once this loop is done, k will have the length of the row. So this will give you the length of pqr[i] (not including the null terminator):

int k;
for (k=0; pqr[i][k] != 0; k++)
    ;
cout<<"The length is "<< k <<endl;

Edit:

You now added that you want to know the size even if the null terminator is not there. There is no way to do that. You will need to either have some kind of terminator, or store the size somewhere. If you use vector<unsigned short>, it will store the size for you. Since it also handles allocation and deallocation, it's the recommended choice.

</Edit>


Note that you have two errors in your allocation:

  1. pqr is an array of pointers, but you're allocating a size of C*sizeof(unsigned short). that should be C*sizeof(unsigned short *) instead.

  2. You're not allocating memory for the null terminator at the end of each string: You should be allocating (strlen(A[i])+1) * sizeof(unsigned short) for each string.

interjay
OMG, I am failing to make you understand that, I want to know the length of pqr[i]. As you see that, I can also know the length from the strlen(A[i]) also....or I appended a '\0' at the end so determining the length of k is pretty easy. The issue is,when I have dynamic data instead of static character array A[3][16], then I will need to detect the column size i.e pqr[i] by doing some kind of sizeof trick. M i clear now dude ?
There's no trick: You have to store the length of each allocated buffer yourself. The easiest way to do this (since you tagged it C++) is to use C++'s `std::vector` and let it do the allocation for you.
Mark B