| | |
Problem with array of pointers
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved |
•
•
Join Date: Jan 2009
Posts: 5
Reputation:
Solved Threads: 0
Hi (first post
),
I have a coursework where we have to read in 50 lines from a file (bubble.txt), sort them into length order and then print them out (its not the whole coursework, just a part). I thought that the only way of holding lines of text in an array is to hold a pointer to each char array in an array called strings.
For some reason (I must admit, pointer do confuse me a bit), whenever I run this code below (just to make sure the lines are in the array) i keep getting the last line (line 50) printed 50 times and I can't tell why.
Any help appreciated.
Kristian Brimble
),I have a coursework where we have to read in 50 lines from a file (bubble.txt), sort them into length order and then print them out (its not the whole coursework, just a part). I thought that the only way of holding lines of text in an array is to hold a pointer to each char array in an array called strings.
For some reason (I must admit, pointer do confuse me a bit), whenever I run this code below (just to make sure the lines are in the array) i keep getting the last line (line 50) printed 50 times and I can't tell why.
Any help appreciated.
Kristian Brimble
c Syntax (Toggle Plain Text)
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "string.h" char *strings[50]; void readLines(void); void printLines(void); int main() { readLines(); printLines(); return 0; } void readLines(void) { FILE *inputFilePtr; inputFilePtr = fopen("bubble.txt", "r"); char line[1000]; for(int i = 0; i < 50; i++) { fgets(line, 1000, inputFilePtr); char *linep = malloc(sizeof(char) * 1000); linep = (char *)&line; strings[i] = linep; } } void printLines(void) { for(int i = 0; i < 50; i++) { printf("%s", strings[i]); } }
Last edited by brimble2010; Jan 6th, 2009 at 4:26 pm.
•
•
Join Date: Jan 2009
Posts: 5
Reputation:
Solved Threads: 0
also, i have added the bubble sort to the code but it isnt swapping the pointers stored in the array and i know it is something to do with the swap method, but i just cant see what it is.
again any help very much appreciated
again any help very much appreciated
c Syntax (Toggle Plain Text)
#include <stdlib.h> #include <stdio.h> #include <string.h> char *strings[50]; void readLines(void); void sortLines(void); void swapLines(int j, int k); void printLines(void); int main() { readLines(); sortLines(); printLines(); return 0; } void readLines(void) { FILE *inputFilePtr; inputFilePtr = fopen("bubble.txt", "r"); char line[1000]; for(int i = 0; i < 50; i++) { fgets(line, 1000, inputFilePtr); char *linep = malloc(sizeof(char) * 1000); strcpy(linep, line); strings[i] = linep; } } void sortLines(void) { for(int i = 0; i < 50; i++) { for(int j = 0, k = 0; k < 50; j++, k++) { int jLen = strlen(strings[j]); int kLen = strlen(strings[k]); if(jLen >= kLen) { swapLines(j, k); } } } } void swapLines(int j, int k) { char *temp = malloc(sizeof(char) * 1000); temp = strings[j]; strings[j] = strings[k]; strings[k] = temp; } void printLines(void) { for(int i = 0; i < 50; i++) { printf("%s", strings[i]); } }
>any chance you could explain what I was doing and what strcpy() does differently, just for future reference?
malloc sets apart the memory you specified. And you keep track of that memory via the pointer linep
But that pointer can be reassigned to point to some other piece of memory. That's what you are forcing it to do here.
I said forcing it, because you are casting it.
Like this
What where you pointing to? To the memory that fgets() used to store the last read string.
When you printf'ed each one of these pointers, all of them yielded the same address, therefore, the last string line read was displayed.
Moral of the story? A pointer is not a string. A string is not a variable.
There's not such a thing as string variable in C, you make a string by joining together many single char variables and terminating it with the '\0'. That's all that keeps the string as a string. A fragile single '\0'.
strcpy() knows how to copy each and every one of this single chars terminating it with '\0', into a piece of memory that you have allocated before hand.
C Syntax (Toggle Plain Text)
char *linep = malloc(sizeof(char) * 1000);
But that pointer can be reassigned to point to some other piece of memory. That's what you are forcing it to do here.
C Syntax (Toggle Plain Text)
linep = (char *)&line;
Like this
linep = &line ; would have gave you an error.What where you pointing to? To the memory that fgets() used to store the last read string.
line[1000]; And then, you stored the same location address, in fifty different pointers. You accomplished that with strings[i] = linep; .When you printf'ed each one of these pointers, all of them yielded the same address, therefore, the last string line read was displayed.
Moral of the story? A pointer is not a string. A string is not a variable.
There's not such a thing as string variable in C, you make a string by joining together many single char variables and terminating it with the '\0'. That's all that keeps the string as a string. A fragile single '\0'.
strcpy() knows how to copy each and every one of this single chars terminating it with '\0', into a piece of memory that you have allocated before hand.
Last edited by Aia; Jan 6th, 2009 at 7:05 pm.
•
•
Join Date: Jan 2009
Posts: 5
Reputation:
Solved Threads: 0
•
•
•
•
What where you pointing to? To the memory that fgets() used to store the last read string.line[1000];And then, you stored the same location address, in fifty different pointers. You accomplished that withstrings[i] = linep;.
When you printf'ed each one of these pointers, all of them yielded the same address, therefore, the last string line read were displayed.

Glad i signed up now
•
•
Join Date: Mar 2008
Posts: 1,438
Reputation:
Solved Threads: 118
C Syntax (Toggle Plain Text)
void swapLines(int j, int k) { char *temp = malloc(sizeof(char) * 1000); temp = strings[j]; // What happened to the 1000 chars you just allocated? strings[j] = strings[k]; strings[k] = temp; }
Remember to free any data you allocate using the free function.
Last edited by William Hemsworth; Jan 6th, 2009 at 7:14 pm.
A few other things you need to learn before you can make that piece of code work properly.
Every time you are about to allocate dynamic memory (like with malloc), you need to keep in mind two things. First, you need to check that the setting apart of that memory was successful.
And second. You need to free that memory when you are finished, using it.
These two things are a must, every time you make use of dynamic memory.
As a bonus. I can let you know about a third concept that you need to be aware.
If you reassign a pointer from dynamic memory like
As you can see, if you put that in a loop, you could waste a lot of memory pretty easily.
When you want to open a file to work on it or read from it, you need to check that it was successful in doing so. Kind of the same that with malloc(). You computer can not work with that file if it could not open it, can't it?
Every time you are about to allocate dynamic memory (like with malloc), you need to keep in mind two things. First, you need to check that the setting apart of that memory was successful.
c Syntax (Toggle Plain Text)
char *linep = malloc(sizeof(char) * 1000); if ( linep == NULL) { /* if you got here, memory was not successfully allocated */ /* you need to handle the error in a proper way, but you can't */ /* count with that memory */ }
And second. You need to free that memory when you are finished, using it.
C Syntax (Toggle Plain Text)
free(linep);
As a bonus. I can let you know about a third concept that you need to be aware.
If you reassign a pointer from dynamic memory like
linep = line; (that would have been the correct way of doing linep = (char *)&line; ), that memory previously allocated is lost for you to use. You don't have a way of getting to it, and it will stay allocated to the program until the program is closed, if the operating system is smart to release it, afterward.As you can see, if you put that in a loop, you could waste a lot of memory pretty easily.
C Syntax (Toggle Plain Text)
inputFilePtr = fopen("bubble.txt", "r");
Last edited by Aia; Jan 6th, 2009 at 7:38 pm.
![]() |
Similar Threads
- Passing 2D Array of Pointers into a function (C++)
- class Array of pointers to objects (C++)
- Problem on array based list (C)
- A CArray of pointers (C)
- Declaration of dynamic pointer array puzzle. (C)
- Messy array things. (C++)
- Trying to use pointers (C++)
- 'C' initializer problem (C)
- Array with names (C)
Other Threads in the C Forum
- Previous Thread: Optimized quicksort implementation
- Next Thread: structure and reading a text file
| Thread Tools | Search this Thread |
* ansi api append array arrays bash binarysearch calculate centimeter changingto char character convert copyanyfile copypdffile creafecopyofanytypeoffileinc createcopyoffile createprocess() dynamic execv fflush file floatingpointvalidation fork forloop frequency function getlogicaldrivestrin givemetehcodez grade graphics gtkwinlinux histogram homework i/o ide inches include infiniteloop initialization input intmain() iso keyboard km license linked linkedlist linux list looping loopinsideloop. lowest matrix microsoft multi mysql oddnumber open opendocumentformat openwebfoundation overwrite pdf pointer pointers posix power program programming pyramidusingturboccodes radix read recursion recv recvblocked reversing scanf scheduling segmentationfault send shape single socketprogramming stack standard strchr string strings suggestions test testautomation threads unix urboc user variable whythiscodecausesegmentationfault win32api windowsapi






