Let's start by clearing up an obvious misunderstanding about pointers.
>char *str;
>fscanf(inp, "%s", str);
This is broken. An uninitialized pointer does not mean a pointer to unlimited space. It means you're not allowed to dereference that pointer or compare it to anything until you initialize it.
You still need to guesstimate a size for reading strings from input, even if that size is a chunk and you append the chunks using dynamic memory. Get that right and then you can worry about an array of strings, because the solution is very similar.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
instead of using malloc() (or realloc) poorly.... might i suggest sticking with the tried and true:
char stringblock[MAX_NUM_LINES][MAX_LINE_LEN];
because i'm fairly certain you're not doing an embedded application that is limited for RAM.
but mangling malloc() like you're doing will certainly find the limits of your computer memory after you fill it full of leaks.
jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
>although you said it is broken I initialize the str every time I read a word from the file.
Hmm, I can interpret this one of two ways:You're saying the code you posted isn't equivalent to the code you're actually using.
You're saying that I'm wrong and the code you posted isn't broken.
If it's the first case then I would highly recommend that you post equivalent examples to your real code if you want any useful help. If it's the second case then I pity you, because I'm very rarely wrong when it comes to the standard language/library, and when I am it's not the people asking beginner questions who are able to correct me successfully.
Arbitrary length input takes more work, and often the basic input functions are weak without a bit of scaffolding around them to get what you want. For example, here's a delimited string input function that can be used to read words:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GROW_BY 32 /* Arbitrary size */
char *reads ( FILE *in, char *delim )
{
char *result = NULL;
size_t size = 0;
size_t capacity = 0;
int ch;
while ( ( ch = getc ( in ) ) != EOF ) {
if ( size == capacity ) {
char *temp;
capacity += GROW_BY;
temp = realloc ( result, capacity + 1 );
if ( temp == NULL ) {
/*
This is a weak solution because it results in
loss of data. Recommend better error handling
*/
free ( result );
result = NULL;
break;
}
result = temp;
}
/* Order is important here; run *after* the resize step */
if ( strchr ( delim, ch ) != NULL )
break;
result[size++] = ch;
}
if ( result != NULL )
result[size] = '\0';
return result;
}
int main ( void )
{
char *s;
while ( ( s = reads ( stdin, " \n" ) ) != NULL ) {
printf ( ">%s<\n", s );
free ( s );
}
return 0;
}
Take careful note of how I handled the memory, this is a common pattern that you can reuse for an array of pointers to char. You can use this example to neatly fix your broken codeand find the answer to the original problem of creating a dynamic array. You're welcome.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
since you apparently don't know how to use malloc without mangling it, i suggested you use
char stringblock[MAX_NUM_LINES][MAX_LINE_LEN];
and you replied I don't know what will be the values of MAX_NUM_LINES and MAX_LINE_LEN values before I read the file and changing these values is not possible after run time I think.
no, of course you cant change them at runtime. so since you dont know what the values are, use ridiculously high values that will cover any possible values. for instance
#define MAX_LINE_LEN 2024
#define MAX_NUM_LINES 512
memory is cheap. what's 1 Meg of memory when you've likely got 1 Gig of RAM? it's better than broken code full of memory leaks because so many programmers have no clue how to properly allocate dynamic memory.
but, really ... go on and use malloc to shoot yourself in the foot. i'm just sticking around for this:In fact it is 2nd case.
Also if you [Narue] have a big experience then you should know it is not a big deal that people can correct you. If you are uncomfortable with that using forums is not suitable for you. I'm not saying I am an expert but you are wrong about what you've written in previous post. Technically speaking, I initialize and reinitiaize str pointer with every word I read from file. It is not a char pointer array it is just a char pointer. After that I make comparison or whatever I need. At least I know that is possible and I suggest you to accept your fault.
*grabs the popcorn*
:D
.
jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
Apparently I don't know usage of malloc
welcome to Daniweb. i'd say of all the people who come in here asking questions that have malloc() somewhere in their code, 90% of them don't have any real concept of how to use it properly. But you're one of the lucky ones: admitting you're powerless is the First Step. now you can stop the abuse cycle, and start the recovery process.As I know segmentation fault occurs when I try to an unallowed/unallocated space in memory.
then why are you arguing with NARUE about your use of uninitialized pointers?
jephthah
Posting Maven
2,587 posts since Feb 2008
Reputation Points: 2,143
Solved Threads: 179
>Technically speaking, I initialize and reinitiaize str pointer with every word I read from file.
You clearly don't understand how memory works in C. Either you use static memory, in which case the compiler takes care of allocation and deallocation, or you have to take care of it yourself (dynamic memory). You can't just expect memory to be there if you're using pointers; if you want to store something with a pointer, the pointer needs to point to allocated memory. "Initializing the pointer" just isn't going to cut it. Afterward, it's your responsibility to deallocate the memory once you're done using it. If you can't handle this kind of responsibility, you shouldn't be using dynamic memory.
Bad memory management is just a segfault waiting to happen. Just because it doesn't occur with a sample of code doesn't mean that it's okay; often times another innocent declaration will be the final push to making your program crap out.
John A
Vampirical Lurker
7,630 posts since Apr 2006
Reputation Points: 2,240
Solved Threads: 339
>Also if you have a big experience then you should
>know it is not a big deal that people can correct you.
It's not a big deal at all...when they're right. Just because you think you're right doesn't mean you are.
>I'm not saying I am an expert but you are wrong
>about what you've written in previous post.
Prove it. I can prove that until you initialize a pointer with an address to memory that you own (ie. an existing array or calling malloc), you invoke undefined behavior. Sometimes undefined behavior appears to work just fine, which is likely what's happening in your case. But "works for me" is a far cry from "correct and bug free".
So tell me, are you truly saying that you believe the following code is 100% correct, that scanf magically allocates memory to s or that s magically points to infinite memory, and that I'm completely wrong in saying that it's broken?
#include <stdio.h>
int main ( void )
{
char *s;
if ( scanf ( "%s", s ) == 1 )
puts ( s );
return 0;
}
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>You can try this one......
Why try something that obviously won't work?
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
You can try this one......
char* str;
while (fscanf(inp, "%s", str) != EOF) {
What size of memory isstr pointing to? You don't know. You haven't given it any meaningful space of memory. Therefore you cannot use it with fscanf(), because it will overwrite unknown memory.
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218