C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 02-10-2009, 01:43 PM   #1
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
2D char array and pointer

Is this okay:
Code:
#include <stdio.h>

void testfunc(char **ray) {
	printf("%c\n",ray[2][2]);		
}


int main () {
	char *ray[5][12]={"this","that","and","more"};
	testfunc((char**)ray);
	return 0;
}
I have been doing it this way for awhile, since it's the only way to pass a "list" to a parameter "char **" without using malloc, and there is no way to assign a functional pointer to char list[5][12]. But today I am thinking that char *list[5][12] might not be what I hope that it is. Altho if it's not, I'm not sure what it would be...
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 02-10-2009, 01:49 PM   #2
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
No, because a char ** is not the same as a char [5][12] or some such. They may appear similar, but when you pass the pointer to char[5][12], you are actually passing a pointer to (*char)[12], not the address of an array of pointers to char.

In this case, you must supply all but the left-most size, e.g.
Code:
void testfunc(char ray[][12]) {
	printf("%c\n",ray[2][2]);		
}


--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 02-10-2009, 02:20 PM   #3
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Further, this is an array of const char* pointers, not a 2D array, which makes it even more wrong.
Of course, since it's an array of pointers, it just happens to work:
Code:
#include <stdio.h>

void testfunc(const char** ray)
{
	printf("%c\n", ray[2][2]);		
}

int main ()
{
	const char* ray[] = { "this", "that", "and", "more" };
	testfunc(ray);
	return 0;
}
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 02-10-2009, 02:22 PM   #4
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Originally Posted by Elysia View Post
Further, this is an array of const char* pointers, not a 2D array, which makes it even more wrong.
The code posted is valid (besides the passing to the function part, that is), it initializes a set of 12-element arrays to the values given by the initializer list.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 02-10-2009, 02:22 PM   #5
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
Quote:
Originally Posted by matsp View Post
No, because a char ** is not the same as a char [5][12] or some such. They may appear similar, but when you pass the pointer to char[5][12], you are actually passing a pointer to (*char)[12], not the address of an array of pointers to char.
By (char*)[12], do you mean:
  • an array of twelve pointers
  • a pointer with the size of 12?
If it is the former, then there really is not a problem (since all the elements will have the same "number", each element of (char*)[12] will be an element of *ray[5]. I suppose the stack size of **ray in testfunc() will be 12x instead of 5x.

What I am mostly worried about is the notation *ray[5][12] implies I could actually have a 3Dish array (a 2D pointer array) and that the "elements" to which I am assigning strings may have sizeof(char*) and not 12. For example, I can now compile this with char *ray[5][12]:
Code:
printf("%s\n",ray[0][0][0]);
where char ray[5][12] would produce a subscipted value error. It segfaults tho.

SInce I don't seem to be producing an overflow (no GUI debugger...) with it, apparently *ray[5][12] is really a 2D char array (a "list") with a pointer to it? Just using ray[5][12] makes a **pointer impossible.

To make a long story short: you don't see a potential overflow in main(), just a possible exceeding of boundaries in testfunc() with the number of elements?

I'm guessing this is because it's easier for the compiler to use an array of pointers with 12 bytes assigned to each rather than to use a pointer to an array of elements with a size of 12 each. So there is no pointer to such a thing possible.

ps. I really really want **char as the argument to testfunct()
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 02-10-2009, 02:26 PM   #6
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Quote:
Originally Posted by matsp View Post
The code posted is valid (besides the passing to the function part, that is), it initializes a set of 12-element arrays to the values given by the initializer list.

--
Mats
Perhaps the code is correct, but I do question if it's intended. Clearly, it is an array of strings, and as thus, in its current form, should be an array of pointer or a 2D array.

Quote:
Originally Posted by MK27 View Post
By (char*)[12], do you mean:
  • an array of twelve pointers
  • a pointer with the size of 12?
No, it's a pointer to an array of 12 elements of type char*.
The actual type should be char (*)[5].

Code:
#include <stdio.h>

void testfunc(char (*ray)[5])
{
	printf("%c\n", ray[2][2]);		
}

int main ()
{
	char ray[12][5] = {"this", "that", "and", "more"};
	testfunc(ray);
	return 0;
}
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.

Last edited by Elysia; 02-10-2009 at 02:35 PM.
Elysia is offline   Reply With Quote
Old 02-10-2009, 02:28 PM   #7
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Sorry, I missed the (very obvious) red star in the original post.

Still, a 2D array is not a pointer to pointer. If you want to do that, then do what Elysia says.

If you want a 2D array of char, and need a pointer to that [e.g. you want to modify the content of the strings in an array of strings], then you need to pass the length of the strings.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 02-10-2009, 02:36 PM   #8
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
Quote:
Originally Posted by Elysia View Post
Of course, since it's an array of pointers, it just happens to work:
That's it. I just noticed it functions as a 3D array in main.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 02-10-2009, 02:41 PM   #9
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
I imagine yours does, because array are laid out sequentially in memory. It just happens to work, but I would definitely say it's undefined.
EDIT: It might just work because you have a pointer to the array (all arrays, 2D or whatever are essentially just one pointer anyway), and as the array is storing pointers, you have an extra pointer in the type and it... works. But if you change it to a 2D array or 3D array you will get trouble.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.

Last edited by Elysia; 02-10-2009 at 02:50 PM.
Elysia is offline   Reply With Quote
Old 02-10-2009, 03:12 PM   #10
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
Hmmm...okay I just noticed this seems to work very nicely, it's only slightly more limited but it still saves a lot of potential malloc and strcpy. I suppose it is the same as just using char[][12] except I can use actual pointers in testfunc() (rather than a local copy):
Code:
#include <stdio.h>
#include <string.h>

typedef struct {
	char X[256];
} string;

void testfunc(string *ray) {
	printf("%s\n",(char*)&ray[2]);
	strcpy((char*)&ray[3],"well done");
}


int main () {
	string ray[4]={"this and that","more and","hello world"};
	testfunc(ray);
	printf("%s\n",(char*)&ray[3]);		
	return 0;
}
You actually don't even need the (char*) casts. The only issue seems to be that -Wall claims:
Code:
test2.c: In function ‘main’:
test2.c:14: warning: missing braces around initializer
test2.c:14: warning: (near initialization for ‘ray[0]’) 
Is this significant and can I get out of it?
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 02-10-2009, 03:15 PM   #11
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
I believe it must be:
Code:
string ray[4] = { { "this and that" }, etc };
One initializer for each struct in the array and one for each member in the struct.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 02-10-2009, 03:16 PM   #12
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
You can get rid of the warning by doing:
Code:
	string ray[4]={{"this and that"},{"more and"},{"hello world"}};
Which is exactly what the compiler told you anyways.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 02-10-2009, 03:41 PM   #13
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
Thanks again people.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 02-10-2009, 06:36 PM   #14
Registered User
 
Join Date: Oct 2008
Location: TX
Posts: 1,262
Perhaps you meant to print the string instead of the character it points to - and here's my 2c.
Code:
#include <stdio.h>

void testfunc(const char *ray[][12])
{
    printf("%s\n",ray[0][2]);
}

int main()
{
    const char *ray[5][12]={"this","that","and","more"};
    testfunc(ray);
    return 0;
}
itCbitC is offline   Reply With Quote
Old 02-11-2009, 12:34 AM   #15
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,945
Quote:
Originally Posted by itCbitC View Post
Perhaps you meant to print the string instead of the character it points to - and here's my 2c.
Perhaps you should have -- nevermind. Anyway all the code I posted works in the way I describe it as working, I wasn't asking for that kind of fix.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Reply

Tags
2d char, pointer

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic array of structures containing yet another dynamic array of structures innqubus C Programming 2 07-11-2008 07:39 AM
pointers InvariantLoop C Programming 13 02-04-2005 09:32 AM
Quick question about SIGSEGV Cikotic C Programming 30 07-01-2004 07:48 PM
Struct *** initialization Saravanan C Programming 20 10-09-2003 12:04 PM
convert long to pointer to char array gazmack C++ Programming 5 09-26-2003 11:33 AM


All times are GMT -6. The time now is 07:51 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22