LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-01-2004, 10:56 PM   #1
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Rep: Reputation: 30
C pointers confusion - char ** = char [][] ??


Hi,

I'm pretty experienced in C - I have worked with C for 9 to 10 years and have done some kernel programming. I was dumbfounded when I realized I couldn't fix this problem. I had always been thinking char **x = char x[10][20] are same except for the fact that no memory (excluding the 4 bytes for the pointer) is reserved for the former case. Looks like its not! I feel like a fool because all these years I thought I was good with C pointers. Help me!

This is what I want to do (kinda pseudo-code - of course the actual code is much more
complex, but this should be enough to get the point across) -

Code:
main()
{
  char list[2][10] = {"Hello","World"};

  somefunc( pass list some how );
  printf("%s -- %s\n", list[0], list[1]);
}

somefunc(param of some data type called "thatlist")
{
 strcpy(thatlist[0], "Test1");
 strcpy(thatlist[1], "Test2");
}
Output should be -

Code:
Test1 -- Test2
This is what I did (actual C code)-

Code:
#include <stdio.h>

void somefunc(char **thatlist);

int main(int argc, char *argv[])
{
 char list[2][10]={"Hello","World"};

 somefunc(list);
 printf("%s -- %s\n", list[0], list[1]);
 return 0;
}

void somefunc(char **thatlist)
{
 strcpy(thatlist[0], "Test1");
 strcpy(thatlist[1], "Test2");
}
And when I compile, I get

Code:
$ gcc test.c -o test
test.c: In function `main':
test.c:9: warning: passing arg 1 of `somefunc' from incompatible pointer type
How should I fix this, so that the output is "Test1 -- Test2" ?

Thanks,
Sarav
 
Old 12-01-2004, 11:10 PM   #2
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
Code:
#include <stdio.h>

typedef char Tmyarray[2][10];

void somefunc(Tmyarray thatlist) {
    strcpy(thatlist[0], "Test1");
    strcpy(thatlist[1], "Test2");
}

int main(int argc, char *argv[]) {
    Tmyarray list={"Hello","World"};
    somefunc(list);
    printf("%s -- %s\n", list[0], list[1]);
    return 0;
}
 
Old 12-01-2004, 11:20 PM   #3
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
Can you explain this please?

Hi,

What was wrong with my previous code? if I can access char **thatlist as thatlist[1][3], etc why is char list[2][10] not same as thatlist? Also what datatype is thatlist in the declaration -

Code:
void somefunc(char thatlist[2][10])
All these days I was thinking the above declaration is not valid or it is a pass by copy. Guess I was wrong. Please explain why my code was wrong and why your code is right. I tested your code and it works, but y? Also, what if I don't know how big x and y are in the declaration char list[x][y]? How should I write a function to handle such a case?

Thanks a lot,
Sarav

Last edited by saravkrish; 12-01-2004 at 11:23 PM.
 
Old 12-01-2004, 11:27 PM   #4
vharishankar
Senior Member
 
Registered: Dec 2003
Distribution: Debian
Posts: 3,178
Blog Entries: 4

Rep: Reputation: 138Reputation: 138
The reason it's an incompatible pointer type is because

char **x is not the same as char x[2][10]! It might sound funny, but that's it...

Try this in the main () function:

Instead of declaring:
Code:
char list[2][10] = { "Hello", "World" };
do this:
Code:
char **list = new char[2][10];

strcpy (list[0], "Hello");
strcpy (list[1], "World");

Last edited by vharishankar; 12-01-2004 at 11:39 PM.
 
Old 12-01-2004, 11:42 PM   #5
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
That doesn't work.

Hi,

Code:
#include <stdio.h>

void somefunc(char thatlist[2][10]) {
    strcpy(thatlist[0], "Test1");
    strcpy(thatlist[1], "Test2");
}

int main(int argc, char *argv[]) {
    char list[2][10]={"Hello","World"};
    printf("%s -- %s\n", list[0], list[1]);
    somefunc(list);
    printf("%s -- %s\n", list[0], list[1]);
    return 0;
}
Doesn't work. I get this error -

Code:
test1.c:13: warning: passing arg 1 of `somefunc' from incompatible pointer type
The code below works, but it's not really useful (read further below) -
Code:
void somefunc(char thatlist[2][10]) {
    strcpy(thatlist[0], "Test1");
    strcpy(thatlist[1], "Test2");
}
I had tried that before asking this question. To rephrase my first question, in actual use, I don't know how big list[][] will be. I pass another param that tells somefunc() how many rows of list there are, so that it doesn't go out of bounds.

How would I code that requirement?

Hari,

Can you explain in words how char **x and char x[2][10] are different? For example, char **x is a pointer to a pointer to a char whereas .... blah blah.

Thanks,
Sarav
 
Old 12-01-2004, 11:47 PM   #6
vharishankar
Senior Member
 
Registered: Dec 2003
Distribution: Debian
Posts: 3,178
Blog Entries: 4

Rep: Reputation: 138Reputation: 138
Don't use the strcpy.

The code compiles all right, but then you get a seg fault if you use strcpy.

This code works perfectly now! The result is what you want!
Code:
#include <stdio.h>
#include <string.h>

void somefunc(char **thatlist);

int main(int argc, char *argv[])
{
 char * list[] = { "Hello", "World" };

 somefunc(list);
 printf("%s -- %s\n", list[0], list[1]);
 return 0;
}

void somefunc(char **thatlist)
{
// dont use strcpy
// strpcy(thatlist[0] "Test1");
// strcpy(thatlist[1], "Test2");
   
    thatlist[0] = "Test1";
    thatlist[1] = "Test2";
}
 
Old 12-01-2004, 11:49 PM   #7
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
The compiler needs to know at compile time the number of columns in a row on a 2dim array to calculate the row offset when you try to use var[][] syntax. Internally it has to use an assembly multiply instruction, but it must know what to multiply your row variable by.
If you don't know the array dimensions at compile time then you can't use [][] to access elements in the array. You'll have to pass a pointer to the first element of the array to the function along with the 2dim array width/height as separate integer arguments, then do the multiply and adding in the function yourself.
I don't know of any other way.
 
Old 12-01-2004, 11:56 PM   #8
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
All,

Is there any other way other than randy's suggestion to pass char *, row and col? It would be nice if I could use thatlist[0], thatlist[1], etc.

Randy,

Thanks. Think it makes sense.

Hari,

I repeat - the actual code is much more complex. Please don't change the question. I want to use strcpy for some reason. I can't paste 300+ lines of code to tell you why I need a strcpy!!!

Thanks,
Sarav
 
Old 12-02-2004, 12:01 AM   #9
vharishankar
Senior Member
 
Registered: Dec 2003
Distribution: Debian
Posts: 3,178
Blog Entries: 4

Rep: Reputation: 138Reputation: 138
In that case, I cannot understand your question. You seem to be assuming that everybody is born to read your mind so how on earth am I supposed to understand your question in the first place? I can only solve your problem with the PROGRAM THAT YOU HAVE PRESENTED HERE and you don't even care to thank me!

I am sorry, but mind-reading is not my talent.
 
Old 12-02-2004, 12:08 AM   #10
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
Hari,

I'm not interested in starting a flame/argument. Thanks for trying to help me and sorry about not making it clear enuf for you.

All,

I'm still interested in other solutions, but I have a feeling that randy is right in that, there is no other way out than what he suggested.

-Sarav
 
Old 12-02-2004, 12:11 AM   #11
vharishankar
Senior Member
 
Registered: Dec 2003
Distribution: Debian
Posts: 3,178
Blog Entries: 4

Rep: Reputation: 138Reputation: 138
Why don't you create a String class yourself and implement that bit of functionality instead of using raw pointers? Pointers are more confusing to use when you start having pointer-to-pointer.

You can store the rows and cols as member variables in the class.
 
Old 12-02-2004, 08:42 AM   #12
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
One of the differences between a char** and char[][] is that with a char[][] you will have a contiguous memory block, and a char** will be a pointer to an array of pointers, which themselves are pointers to a char....

If you consider for a moment what you have to do to dynamically allocate memory for a char**, it might make more sense.

Code:
char** pBlah = new char*[10];

for (int c=0;c<10;c++)
{
     pBlah[c] = new char[10];
}
Obviously, you are not going to have a contiguous block of memory in the above case...

One possible alternative to your problem might be do pass your data in as if it were a single dimension array. For instance something like so might work:

Code:
#include <stdio.h>

void DumpMatrix(int *pVals, int rows, int columns);

int main()
{
    int matrix[4][4];
    int x, y;

    for (y=0;y<4;y++)
    {
        for (x=0;x<4;x++)
        {
            matrix[y][x] = y*4+x;
        }
    }

    DumpMatrix((int*)matrix, 4, 4);

    return 0;
}

void DumpMatrix(int *pVals, int rows, int columns)
{
    int x,y;

    for (y=0;y<rows;y++)
    {
        for (x=0;x<columns;x++)
        {
            int index = y*columns+x;
            printf("%d ", pVals[index]);
        }
        printf("\n");
    }
}
Results:
Code:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

Last edited by deiussum; 12-02-2004 at 08:48 AM.
 
Old 12-02-2004, 10:06 AM   #13
saravkrish
Member
 
Registered: Mar 2004
Location: KY, USA
Distribution: Fedora Core 1
Posts: 190

Original Poster
Rep: Reputation: 30
Hari,

That would be C++. I'm using C now and I'm not very familiar with C++. I use Java for OOP.

Hi deiussum,

That's what randy suggested and that's what I'm using right now.

Thanks,
Sarav.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
array of char pointers djgerbavore Programming 2 01-08-2005 01:59 PM
C Problem---convert char to char* totti10 Programming 11 11-06-2004 11:32 AM
invalid conversion from `char' to `const char* bru Programming 6 05-09-2004 03:07 PM
convert from char* to unsigned char* D J Linux - Software 2 02-20-2004 04:09 AM
Help with getgrnam_r and char ** pointers paradoxicalogic Programming 1 08-20-2003 12:03 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:37 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration