LinuxQuestions.org
Visit the LQ Articles and Editorials section
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 09-10-2009, 09:53 AM   #1
richmike3
LQ Newbie
 
Registered: Sep 2009
Posts: 11

Rep: Reputation: 0
Question Memory Access Violation - C Programming


Hi All,

I have problem to access a memory location in 2 dimensional array.

code snippet,

function (char **strArray)
{
while (strArray != NULL)
{
printf ("%s\n", *strArray);
strArray++;
}
}

consider strArray holds 5 string value.
while (strArray != NULL) not terminating after parsing 5 string values.

What was the best check to terminate while loop after parsing 5 string values?
Is there any memory validation method available?

Thank you.

-Mr S
 
Old 09-10-2009, 10:08 AM   #2
orgcandman
Member
 
Registered: May 2002
Location: dracut MA
Distribution: Ubuntu; PNE-LE; LFS (no book)
Posts: 594

Rep: Reputation: 102Reputation: 102
It is better practice to keep track of the number of elements in your array with a separate variable, and then pass both into the function.
 
Old 09-10-2009, 10:26 AM   #3
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,107

Rep: Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114
Quote:
Originally Posted by richmike3 View Post
consider strArray holds 5 string value.
while (strArray != NULL) not terminating after parsing 5 string values.
There is no reason it should. The value after the end of the array is not necessarily NULL.

Quote:
Is there any memory validation method available?
If there were, that wouldn't help either. The value after the end of the array is not necessarily an invalid memory address.

I'm only guessing at the context of your problem, but based on that guess, I think you should modify the original source of the array of pointers so that it always allocates one more than the number of actual pointers and always makes sure that extra one (at the end) is NULL.

If the array is static or global, the compiler/linker/loader will make sure the extra is NULL as long as you allocate one more than you initialize. But if the array is stack or heap, you need run time code to set the extra pointer to NULL.
 
Old 09-10-2009, 01:25 PM   #4
karlatLQ
Member
 
Registered: Sep 2009
Posts: 67

Rep: Reputation: 19
Try printing just one string

Did you get a segmentation fault when you tried to run it? That is what it looks like you would get. Have you tried to print just one string in the same manner without the loop? I think that you will get a segmentation fault too. Give that a try!

Post the initialization code too.
 
Old 09-11-2009, 04:08 AM   #5
richmike3
LQ Newbie
 
Registered: Sep 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Thanks orgcandman,

But, that won't suite best for me. Would you please suggest me more.
Thanks.

-Mr S
 
Old 09-11-2009, 04:24 AM   #6
richmike3
LQ Newbie
 
Registered: Sep 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Thanks Johnsfine,

For string array, I can add NULL end, OK. Think about int array. -1 will be a value, I can't add it at end.

Please let me know how can find array is ended.

Thanks
 
Old 09-11-2009, 04:28 AM   #7
richmike3
LQ Newbie
 
Registered: Sep 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Hi KarlatLQ,
I can print single string without any error.

Initialization snippet is,

char **strArray;
strArray = (char**) malloc (5 * sizeof(char*));
for (i = 0; i < 5; i++)
{
*strArray = (char*) malloc (5 * sizeof (char));
strArray++;
}

Last edited by richmike3; 09-11-2009 at 04:30 AM.
 
Old 09-11-2009, 04:57 AM   #8
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 809

Rep: Reputation: 178Reputation: 178
Code:
  while (strArray != NULL)       /* wrong */
  while (*strArray != NULL)      /* right */
Also, your initialization snippet does not ensure that the final pointer is followed by a NULL pointer. Try this:
Code:
char **strArray;
strArray = (char**) malloc (6 * sizeof(char*));
for (i = 0; i < 5; i++)
{
*strArray = (char*) malloc (5 * sizeof (char));
strArray++;
}
strArray[5]=NULL;

Last edited by wje_lq; 09-11-2009 at 05:01 AM.
 
Old 09-11-2009, 08:32 AM   #9
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,107

Rep: Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114
Quote:
Originally Posted by richmike3 View Post
For string array, I can add NULL end, OK. Think about int array. -1 will be a value, I can't add it at end.

Please let me know how can find array is ended.
Since no reserved value is available, you need to have the length stored somewhere that can be accessed where needed.

I understand you do not want to pass two variables when passing the array. How about:

to allocate it
Code:
int* my_array = malloc( (desired_size+1)*sizeof(int) );
*(my_array++) = desired size;
to deallocate it
Code:
free(my_array-1);
to use it
Code:
function( int* array ) {
int ndx;
for ( ndx=0; ndx<array[-1]; ++ndx ) {
  do something with array[ndx]
}
}
So except for the allocate/deallocate, everything else can treat it as a nearly ordinary array that happens to have its element count stored at array[-1].

Quote:
Originally Posted by wje_lq View Post
Code:
  while (strArray != NULL)       /* wrong */
Very sloppy of me failing to notice that error in the original post. Usually I look more carefully.

Last edited by johnsfine; 09-11-2009 at 08:34 AM.
 
Old 09-11-2009, 12:27 PM   #10
karlatLQ
Member
 
Registered: Sep 2009
Posts: 67

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

void main(void)
{
        int i=0;
        char *string[]={"monday","tuesday","wednesday","thursday","friday"};

        for (i=0; i<5; i++)
                printf("%s\n", string[i]);

        return;
}
Try this code. To compile it and to run it:

Code:
> gcc file.c
> /path/to/exe/a.out
You will see that it outputs the five days of the week. Using this type of string array, your program could be made to work right.
 
Old 09-12-2009, 11:41 AM   #11
richmike3
LQ Newbie
 
Registered: Sep 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Thank you guys.

I added NULL at end for string array and -1 at the end for int array.
 
Old 09-12-2009, 06:58 PM   #12
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 217

Rep: Reputation: 21
It seems to me that you want to use an array with program arguments argv[].?
An array of arguments is defined like this:
Code:
char *arg[] = {"progname", "op1", (char)0 };
So the end will be detected with:
Code:
while( arg[i] != 0 )
...
So there is no need to search for NULL but for 0 !
And if not, 0 terminated strings are c-strings and will always be handled right by the system !
With NULL there is expressed the need of a char with value 0 and not the character '0' (with value 48).
 
Old 09-13-2009, 08:40 AM   #13
karlatLQ
Member
 
Registered: Sep 2009
Posts: 67

Rep: Reputation: 19
What compiler are you using?
Could you post the code where you set the string values to the array?

Could you post a test code to print out just one of the arrays in the string?

Quote:
while (strArray != NULL)
{
printf ("%s\n", *strArray);
strArray++;
}
What happened when you tried to run that code? Have you read about pointer arithmetic? I do not think that is what you want to do. Try this piece of code to see what happens:

Code:
printf("\nstrArray = %X", strArray);
strArray++;
printf("\nstrArray = %X", strArray);
What is the program for?
 
Old 09-14-2009, 08:58 AM   #14
orgcandman
Member
 
Registered: May 2002
Location: dracut MA
Distribution: Ubuntu; PNE-LE; LFS (no book)
Posts: 594

Rep: Reputation: 102Reputation: 102
Quote:
Originally Posted by bastl View Post
It seems to me that you want to use an array with program arguments argv[].?
An array of arguments is defined like this:
Code:
char *arg[] = {"progname", "op1", (char)0 };
So the end will be detected with:
Code:
while( arg[i] != 0 )
...
So there is no need to search for NULL but for 0 !
And if not, 0 terminated strings are c-strings and will always be handled right by the system !
With NULL there is expressed the need of a char with value 0 and not the character '0' (with value 48).
FYI - on intel machines, NULL is 0. On other machines, 0 might be a valid address, so using it as a 'special case' is a bad idea (notably, SV5R4 used 0 as a valid address, and linux can emulate this behavior). It is best practice to check explicitly for NULL, which the C library on your platform 'guarantees' to be correct.

Example:
Quote:
[09:53:11][aconole@weston:~]
$ cat null.c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
printf("Null [%X]\n", NULL);
return 0;
}
[09:53:16][aconole@weston:~]
$ gcc -o null null.c
[09:53:18][aconole@weston:~]
$ ./null
Null [0]
[09:53:19][aconole@weston:~]
$
As for how arrays are built, you are partly correct for the arguments pointer, but that's because of the exec() specifications. From the manual:
Quote:
The list of arguments must be terminated by a NULL pointer, and, since these are variadic functions, this pointer must be cast (char *) NULL.
-Aaron
 
Old 09-14-2009, 10:52 AM   #15
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 217

Rep: Reputation: 21
Quote:
Originally Posted by orgcandman View Post
FYI - on intel machines, NULL is 0. On other machines, 0 might be a valid address, so using it as a 'special case' is a bad idea (notably, SV5R4 used 0 as a valid address, and linux can emulate this behavior).
-Aaron
Sorry, but NULL is never 0x0000:0x0000, this is the address of the first instruction when you turn on or reset your computer and not only Intel. So you would call the first BIOS instruction with NULL - no, NULL is never 0x0000 nor (char) 0, NULL will always be a address different from 0x0000:0x0000 and With c++ you even can't be sure that NULL from a parent is the same NULL of a child. In that case you even can't search for NULL at all. In sure Linux will have an other NULL as you in your program!
And linux system always needs (char) 0 terminated strings like char *st="hallo" is one, and linux needs also the array to be 0 terminated.
NULL only means that it is a pointer to its self and if NULL is used for a call, instead of a function, some POPs and a ret will be added after. So every NULL you use instead of a different function type will be a different NULL !
 
  


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
Linux-2.6.25.4 , memory violation at while executing "run_init_process(/sbin/init)" saikiran.veluri Linux - Newbie 1 07-04-2009 01:04 PM
Gentoo: Access Violation while compiling Autoconf-2.63 clintonsk Linux - Newbie 6 10-11-2008 06:28 PM
access Samba server: control violation /etc/rc.d/init.d/smb start failed Paul.Hermans Mandriva 1 07-25-2005 04:46 PM
Access Violation??? sh4k3y Linux - Software 3 03-25-2004 07:22 AM
WINE access violation problem Campitor Linux - Software 0 09-30-2003 11:24 AM


All times are GMT -5. The time now is 12:00 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration