char pointer length problem
Hi All,
I am trying to get the length of an char pointer but the app is getting crashed by giving error - Access Violation. I am not getting why this is happening. The piece of code is given below -
CODE
Code:
int length = 0;
char** strArr = (char**)malloc(sizeof (char * )*(4));
temp=(char*)malloc(sizeof(char*)*100);
tempChar="HELLO";
strArr[0] = (char*)malloc(sizeof(char*)*(strlen(tempChar)+1));
strcpy(strArr[0],tempChar);
tempChar="HELLO1";
strArr[1] = (char*)malloc(sizeof(char*)*(strlen(tempChar)+1));
strcpy(strArr[1],tempChar);
tempChar="HELLO2";
strArr[2] = (char*)malloc(sizeof(char*)*(strlen(tempChar)+1));
strcpy(strArr[2],tempChar);
tempChar="HELLO3";
strArr[3] = (char*)malloc(sizeof(char*)*(strlen(tempChar)+1));
strcpy(strArr[3],tempChar);
length = get2DArrayLength(strArr);
int get2DArrayLength(char** charArray)
{
int len=0;
char **ptr;
for(ptr=charArray;ptr!='\0';*ptr++)
{
print("0..%s",*ptr);
if(*ptr==NULL)
break;
if(strlen(*ptr)!=0)
{
len+=strlen(*ptr);
}
print("1..%s",*ptr);
}
return len;
}OUTPUT ::
0..HELLO
1..HELLO
0..HELLO1
1..HELLO1
0..HELLO2
1..HELLO2
0..HELLO3
1..HELLO3
segmentation fault
Please check the code and tell me what I am doing wrong in this..
thanks.
[1460 byte] By [
pankajb] at [2007-11-20 10:50:29]

# 1 Re: char pointer length problem
You can't calculate the length like that. In matter of fact, there's a lot of things that are wrong in your code. You can't assume that the end of the array there's NULL, which you can use to determine the end of the array. No. At the end of the array there's just some random memory that could be anything, furthermore it's invalid to even try accessing it (which is what you're trying to do), which is leading to a segmentation fault.
Basically, there's no way to calculate the size of a dynamically allocated array like that. You just need to pass the size around to know what the boundaries are. I highly recommend using STL containers if you're using C++, since it keeps track of the size for you.
# 2 Re: char pointer length problem
for(ptr=charArray;ptr!='\0';*ptr++)
Why do you expect that the ptr will sometime be equal to '\0' ? It will not become '\0' since the array of pointers to char is not ended at address '\0' (which may or may not be equal to NULL or 0).
You should pass the size of the array and iterate until reaching it's end.
Zachm at 2007-11-9 1:25:39 >

# 3 Re: char pointer length problem
You can't calculate the length like that. In matter of fact, there's a lot of things that are wrong in your code. You can't assume that the end of the array there's NULL, which you can use to determine the end of the array. No. At the end of the array there's just some random memory that could be anything, furthermore it's invalid to even try accessing it (which is what you're trying to do), which is leading to a segmentation fault.
Basically, there's no way to calculate the size of a dynamically allocated array like that. You just need to pass the size around to know what the boundaries are. I highly recommend using STL containers if you're using C++, since it keeps track of the size for you.
Hi reko_t,
Thanx for the reply,
Actually I am doing all this in BREW,
I have to calculate the length dynamically as I am allocating the pointer runtime and deallocating also runtime as if I will use char** then I have to use one integer to keep track of size of the first diamention. so for each char** I have to use different integers. I don't want to do use such manual solution. I want it to do dynamically. I don't have the support for STL containers.
So please tell me is there any other way out for this
Thanx
# 4 Re: char pointer length problem
Just take a look at this code it shows what exactly I am doing-
#include <iostream>
#include <stdio.h>
using namespace std;
void main()
{
char ** xyz;
int len=0,bh=0,i=0;
cin>>len>>bh;
xyz = (char **)malloc(sizeof(char *)*len);
memset(xyz,NULL,(sizeof(char *)*len));
for(i=0;i<len;i++)
{
xyz[i] = (char*)malloc(sizeof(char)*bh);
memset(xyz[i],NULL,(sizeof(char)*bh));
}
for(i=0; i<len;i++)
{
cin>>xyz[i];
cout<<strlen(xyz[i])<<endl;
}
char **ptr = xyz;
cout<<"now data count is "<<endl;
len = 0;
for(ptr = xyz; ptr != '\0' ;*ptr++)
{
if(*ptr==NULL)
break;
if(strlen(*ptr) != 0)
{
len += strlen(*ptr);
cout<<strlen(*ptr)<<endl;
}
}
cout<<"Total length is "<<len<<endl;
}
# 5 Re: char pointer length problem
I don't want to do use such manual solution. I want it to do dynamically.First, use code tags when posting code. This is in the dev-archive posting FAQ.
Second, the main() function returns int, not void.
Third, you are using C++, since you are including iostream. Why are you creating string arrays this way (in a 'C' like manner?).
Fourth, I do not know what BREW is supposed to be, but all you have are pointers. A pointer is just a value denoting the address of a variable. That's it, nothing more than that. All of those calls to malloc() doesn't change this fact. A pointer knows nothing about how much memory you allocated.
Add to the fact that when you pass just a char**, there is absolutely no information to the calling function as to how to iterate through it correctly. The function needs row/column sizes to do the correct iterations.
Therefore, you must pass the number of dimensions around, or create your own array class and have the row/colums as members, or use vectors. If you can't do this, then choose another language because C++ cannot do what you want by just passing naked char** pointers with no other information associated with them.
Maybe you can explaing to us what BREW is supposed to be, and what it expects. I bet even this BREW thing requires row/column information, not just raw data.
Regards,
Paul McKenzie
# 6 Re: char pointer length problem
Hi Paul,
Thanx for the reply,
Add to the fact that when you pass just a char**, there is absolutely no information to the calling function as to how to iterate through it correctly. The function needs row/column sizes to do the correct iterations.
That's what I am talking of I need the diamentions i.e row and columns.
in char** by using strlen() I'll easily get the value of the column.
but here In my case I need the row value to be get calculated run time.
as at runtime it will be getting decided that how many rows are there.
How should I get this row information of char** at runtime?
Thanx
# 7 Re: char pointer length problem
Just take a look at this code it shows what exactly I am doing- So the question is why do you think that this should be NULL?
if(*ptr==NULL)
A pointer is not guaranteed to be equal to NULL unless *you* made it NULL, or it was declared as a global variable.
Create an extra pointer at the end of the sequence and set it to NULL, and then use that as the sentinel value.
Regards,
Paul McKenzie
# 8 Re: char pointer length problem
but here In my case I need the row value to be get calculated run time. as at runtime it will be getting decided that how many rows are there.
How should I get this row information of char** at runtime?Whatever variable you assigned the number of rows to, just pass that variable along with the char** pointer to whatever function you're calling.
There is no other way to do what you want using just char**.
Regards,
Paul McKenzie
# 9 Re: char pointer length problem
Whatever variable you assigned the number of rows to, just pass that variable along with the char** pointer to whatever function you're calling.
that's what I am doing currently in my project. But it's a manual solution to get the no of rows.
So for each char** I had to keep 1 integer to keep track of rows allocated.
There is no other way to do what you want using just char**.
as I moved from Java to C -
Java has the support for getting the length of an 2 diamentional string array, and Java is built up over C.
So I thought It also be possible to do the same here -
Thanx
# 10 Re: char pointer length problem
that's what I am doing currently in my project. But it's a manual solution to get the no of rows.
So for each char** I had to keep 1 integer to keep track of rows allocated.Sorry, that's the way pointers work. You still haven't clearly stated why you need to even code this way. What is this BREW thing?
as I moved from Java to C -Java isn't C.
and Java is built up over C.No it isn't. Java is a different language than 'C', and attempting to write C code because you can do it in Java is the wrong approach.
So I thought It also be possible to do the same here - No, it cannot be done.
Regards,
Paul McKenzie
# 11 Re: char pointer length problem
Hi Paul,
Thanks for the reply,
I had found the solution for this-
please tell me is it the right way or not?
#include <iostream>
#include <stdio.h>
using namespace std;
int get2DArrayLength(char** ptr);
int main()
{
char** xyz;
int len=0,bh=0,i=0;
cin>>len>>bh;
xyz = (char**)malloc(sizeof(char*)*(len+1));
memset(xyz,NULL,(sizeof(char*)*(len+1)));
for(i=0;i<len;i++)
{
xyz[i] = (char*)malloc(sizeof(char)*bh);
memset(xyz[i],NULL,(sizeof(char)*bh));
}
for(i=0; i<len;i++)
{
cin>>xyz[i];
cout<<strlen(xyz[i])<<endl;
}
cout<<"Total length is "<<get2DArrayLength(xyz)<<endl;
}
int get2DArrayLength(char** ptr){
int len = 0;
while(ptr[len]!=NULL){
cout<<"STRING :: "<<ptr[len]<<endl;
len++;
}
return len;
}
# 12 Re: char pointer length problem
as I moved from Java to C -
Java has the support for getting the length of an 2 diamentional string array,If you want similar sort of functionality then you should do as suggested earlier and ignore C and concentrate on C++ with STL. Multiple dimensioned arrays/strings are too much like hard work in C :sick: and error prone :eek:
# 13 Re: char pointer length problem
Hi Paul,
Thanks for the reply,
I had found the solution for this-
please tell me is it the right way or not?
#include <iostream>
#include <stdio.h>
using namespace std;
int get2DArrayLength(char** ptr);
int main()
{
char** xyz;
int len=0,bh=0,i=0;
cin>>len>>bh;
xyz = (char**)malloc(sizeof(char*)*(len+1));
memset(xyz,NULL,(sizeof(char*)*(len+1)));
for(i=0;i<len;i++)
{
xyz[i] = (char*)malloc(sizeof(char)*bh);
memset(xyz[i],NULL,(sizeof(char)*bh));
}
for(i=0; i<len;i++)
{
cin>>xyz[i];
cout<<strlen(xyz[i])<<endl;
}
cout<<"Total length is "<<get2DArrayLength(xyz)<<endl;
}
int get2DArrayLength(char** ptr){
int len = 0;
while(ptr[len]!=NULL){
cout<<"STRING :: "<<ptr[len]<<endl;
len++;
}
return len;
}
No you can't do that. <iostream> isn't part of C, nor is cout or cin or endl nor is there such a thing in C as using or namespace.
(by the way these things do exist in C++ but if that is what you are using then you should throw away all that mallocing and use string and vector)
# 14 Re: char pointer length problem
Hi Paul,
Thanks for the reply,
I had found the solution for this-
please tell me is it the right way or not?
First, the following code accomplishes the same thing:
#include <vector>
#include <string>
#include <iostream>
typedef std::vector<std::string> StringArray;
using namespace std;
int getArrayLength(const StringArray& a);
int main()
{
int len=0,bh=0,i=0;
cin>>len;
StringArray xyz(len);
for(i=0; i<len;i++)
{
cin >> xyz[i];
cout << xyz[i].length() << endl;
}
cout << getArrayLength(xyz);
}
int getArrayLength(const StringArray& a)
{
return a.size();
}
So exactly what is the reason you can't use the code above? You say you know Java, this is as close to Java as you can find when coding C++. Resorting to low-level C routines (even to the point of using malloc() instead of new[]) is not necessary at all.
As to your code, it is incorrect in the sense that it doesn't release any memory, so it is full of memory leaks.
Regards,
Paul McKenzie
# 15 Re: char pointer length problem
Pankaj,
inside Get2DArrayLength(char ** ptr){...} you cannot find the end of the array of char *s that ptr points to by comparing ptr[len] to NULL unless you leave one char* at the end which gets set to null through your memset, just like Paul told you before, and you said something about an interger or something but the code you posted in "I got a solution" does not reflect any change of that manner.
So, in the ridiculous looking C/C++ (pointlessly mixed, either do it in C++ as Paul showed it or use plain simple C and leave out all your cins and couts. (or are you mixing it just so you can use the syntactically easier cin and couts?) you said you don't have access to STL, then how come you have access to <iostream> ? better work a bit harder and put in all those scanf and printfs instead of making it C++ just to cheat with the cin and cout s) code that you have, in the loop where you read all the xyz[i] s, run the loop len-1 times instead of len times.
i.e. make the comparison as i<len-1 in the loop where you did cin>>xyz[i].
That will make your Get2DArrayLength() find the NULL at the end and therefore work correctly.
Indrajit
# 16 Re: char pointer length problem
Hi Paul,
is there way out for the same thing in c?
thanx
# 17 Re: char pointer length problem
Hi Paul,
is there way out for the same thing in c?
thanxI told you what the way "out" was. It is to pass the number of rows to the function you are calling. Other than that, there is no other way. The function that you're calling cannot work with a char** alone. That is how 'C' and C++ works. Again, this isn't Java.
Also, here is a *much* better way of creating a 2d array in 'C':
#include <stdlib.h>
#include <stdio.h>
char **CreateMatrix(int nRows, int nCols, char InitValue)
{
char ** pMatrix;
int index;
int index2;
char *pBytes, *pStart;
/* Allocate rows */
pMatrix = (char **) calloc(nRows, sizeof(char*));
/* Now allocate the total number of bytes needed to fill matrix */
pBytes = (char *)calloc(nCols * nRows, sizeof(char));
/* Point to start of allocated data */
pStart = pBytes;
/* Now point the row pointers in the right place in the memory pool */
for ( index = 0; index < nRows; index++ )
{
pMatrix[index] = (char *)pStart;
pStart += nCols * sizeof(char);
}
/* Initialize to initial value */
for ( index = 0; index < nRows; index++ )
{
for ( index2 = 0; index2 < nCols; index2++ )
pMatrix[index][index2] = InitValue;
}
return pMatrix;
}
/* function to free matrix */
void FreeMatrix( char **pMatrix )
{
free( pMatrix[0] ); /* Free pool of data */
free( pMatrix ); /* Free row pointers */
}
typedef struct tagCharMatrix
{
char **Matrix;
int nrows;
int ncols;
} CharMatrix;
int GetNumRows(const CharMatrix* mat)
{
return mat->nrows;
}
int GetNumColumns(const CharMatrix* mat)
{
return mat->ncols;
}
void AllocateMatrix(CharMatrix* mat, int nrows, int ncols)
{
mat->Matrix = CreateMatrix(nrows, ncols, '\0');
mat->nrows = nrows;
mat->ncols = ncols;
}
void DestroyMatrix(CharMatrix* mat)
{
FreeMatrix(mat->Matrix);
mat->Matrix = NULL;
}
void DoSomethingWithMatrix(CharMatrix *mat)
{
// whatever
}
int main()
{
CharMatrix mat;
AllocateMatrix(&mat, 10, 10);
printf("The number of rows is %d\n", GetNumRows(&mat));
printf("The number of columns is %d\n", GetNumColumns(&mat));
DoSomethingWithMatrix(&mat);
DestroyMatrix(&mat);
}
So you pass a CharMatrix, which contains all the information necessary. Not only does this create a matrix in a very generic way, it also provides a function to destroy the matrix.
Regards,
Paul McKenzie
# 18 Re: char pointer length problem
Hi Paul,
Thanx for the code.
It's really a very nice way of using char pointers.
It will help me the most.
Also I had tried some things plz check for the same -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get2DArrayLength(char** ptr);
int get3DArrayLength(char*** ptr);
void main()
{
char*** xyz;
int len=0,len1=0,bh=0,i=0,j=0;
printf("ENTER LENGTH OF 1st Diamention :: ");
scanf("%d",&len);
printf("\nENTER LENGTH OF EACH STRING :: ");
scanf("%d",&bh);
xyz = (char***)malloc(sizeof(char**)*(len+1));
memset(xyz,NULL,(sizeof(char**)*(len+1)));
for(i=0;i<len;i++)
{
printf("\nENTER LENGTH OF 2nd Diamention :: ");
scanf("%d",&len1);
xyz[i] = (char**)malloc(sizeof(char*)*(len1+1));
memset(xyz[i],NULL,(sizeof(char*)*(len1+1)));
for(j=0;j<len1;j++)
{
xyz[i][j] = (char*)malloc(sizeof(char)*bh);
memset(xyz[i][j],NULL,(sizeof(char)*bh));
printf("\nENTER STRING :: ");
scanf("%s",xyz[i][j]);
printf("\nENTERED STRING LENGTH :: %d",strlen(xyz[i][j]));
}
printf("\n");
}
printf("\n\n3D Total Length is :: %d\n",get3DArrayLength(xyz));
}
int get2DArrayLength(char** ptr){
int len = 0;
while(ptr[len]!=NULL){
printf("\nSTRING :: %s -- LENGTH :: %d",ptr[len],strlen(ptr[len]));
free(ptr[len]);
len++;
}
free(ptr[len+1]);
free(ptr);
return len;
}
int get3DArrayLength(char*** ptr){
int len = 0;
while(ptr[len]!=NULL){
printf("\n2D Total length is :: %d",get2DArrayLength(ptr[len]));
len++;
}
free(ptr[len+1]);
free(ptr);
return len;
}
This code has 1 memory lick at the line -
xyz[i][j] = (char*)malloc(sizeof(char)*bh);
I am not getting why exactly it's coming there as I am freeing all the memory allocated.
Please check for the same.
Thanx
