1

So I have a list of structures and I allocated space to them with malloc(), using *p. Now I want to get access to every ptrletter element and use it. How should I do that? Here's my code.

typedef struct Words {
   char *ptrletter;
   int numbers;
} Word;

int main(){

    FILE *f, *g;    
    char c,d;    
    int *a;    
    int nrofline=0;    
    int elements=0;    
    char string[2];    
    int lines=0;
    f=fopen("m_in.txt","r");

    do{
        d=fgetc(f);
        if (d=='\n'){
            lines++;
        }
    }while (d!=EOF);

    a=(int*)malloc(sizeof(int)*lines);
    rewind(f);

    lines=0;

    do{
        d=fgetc(f);
        if ((d>='A' && d<='Z') || (d>='a' && d<='z')){
            elements++;
        }
        if (d=='\n'){
            a[lines]=elements;
            lines++;
            elements=0;
        }
    }while (d!=EOF);

    Word *p=(Word*)malloc(sizeof(Word)*lines);

    int j=0;
    for (j=0; j<lines; j++){
        strcpy(p[j].ptrletter,"");
        p[j].numbers=0;
    }

    rewind(f);
}

I get error at the strcpy() part (almost the last one) and I have tried to search for an error on google but I haven't found anything useful. It must be dynamically allocated.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Lilla Nagy
  • 91
  • 1
  • 2
  • 11
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Jan 12 '16 at 20:40
  • It must be dynamically allocated, but you are not allocating it. – Iharob Al Asimi Jan 12 '16 at 20:41
  • you must use the `->` operator to access the contents of a structure pointer – Magix Jan 12 '16 at 20:41
  • iharob you mean I have to allocate every p[j] element before I can do that? Magix I tried that but it gives me this error: invalid type argument of '->' (have 'Word') – Lilla Nagy Jan 12 '16 at 20:43
  • @LillaNagy your single `malloc()` already allocated all of the `p[j]` elements. The problem is each of those elements contains a pointer (`ptrletter`) that is not yet valid; you must allocate those (as addressed in the answer below). – mah Jan 12 '16 at 20:45
  • Where do you have a list? That is just an array. – too honest for this site Jan 12 '16 at 21:05
  • when calling the function: `malloc()`, 1) in C, do not cast the returned value. In C, the type is `void*` which can be assigned to any pointer. casting just clutters the code, making it more difficult to understand, debug, maintain. 2) always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Jan 13 '16 at 15:38
  • for readability and understandability by us humans, please follow the axiom: only one statement per line and (at most) one variable declaration per statement. – user3629249 Jan 13 '16 at 15:39
  • when calling the function: `fopen()`, always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Jan 13 '16 at 15:43
  • regarding this line: `d=fgetc(f);` the function: `fgetc()` returns an `int` so the variable `d` should be declared as: `int d;` – user3629249 Jan 13 '16 at 15:46
  • there is a logic error in the counting of `lines` as the input file may be missing a final '\n', so the code should be tracking if it is reading a line that has chars in it. and if so and EOF is encountered, then should increment `lines` one more time. – user3629249 Jan 13 '16 at 15:50
  • to avoid some implicit conversions, the variable `lines` should be declared as: `size_t lines;` and `j` should be declared as: `size_t j;` – user3629249 Jan 13 '16 at 15:56
  • the function: `rewind()` is really for tape drives. much better to use: `fseek()` – user3629249 Jan 13 '16 at 16:04
  • by inserting `#include ` then this line: `if ((d>='A' && d<='Z') || (d>='a' && d<='z')){` can be simplified to: `if ( isalpha( d ) ) {` – user3629249 Jan 13 '16 at 16:11
  • this line: `}while (d!=EOF);` will fail, in the posted code, if your system defines `char` as `unsigned` – user3629249 Jan 13 '16 at 16:14
  • the last call to rewind(f); should be: fclose( f ); free(a); free(p); – user3629249 Jan 13 '16 at 16:16
  • strongly suggest: when making a comparison to a literal, always place the literal on the left of the `==` operator, Then, if a keystroke error is made, for instance only using: `=`, then the compiler will find the error, rather than you spending many an hour searching the code, with your eye/mind skipping right over the problem. – user3629249 Jan 13 '16 at 16:20
  • reading a file one character at a time, using `fgetc()` is orders of magnitude slower than reading it using something like `fgets()` or `getline()` then looping through the line, char by char. – user3629249 Jan 13 '16 at 16:31

1 Answers1

5

In your code,

strcpy(p[j].ptrletter,"");

p[j].ptrletter is also a pointer which has not been allocated any memory. Without a proper allocation, the pointer points to invalid memory, using which leads to undefined behavior.

You can use malloc() or family to allocate memory to p[j].ptrletter before you can actually use it.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261