I cannot seem to find why this is stack smashing, the code is meant to read in some files, read each line and cat other lines on the end. but i get a stack smashing detected error at the very end of code.
Any ideas?
Code is :
void main (int argc, char *argv[])
{
char lineCount;
int count = 0;
size_t buffer_size = 40;
char *buffer =malloc(buffer_size * sizeof(char));
char *buffer2 =malloc(buffer_size * sizeof(char));
char *buffer3 =malloc(buffer_size * sizeof(char));
char *buffer4 =malloc(buffer_size * sizeof(char));
FILE *Dictionary, *Names;
Dictionary = fopen ("/home/overdog/Documents/Coding/dictionary.txt","r");
Names = fopen ("/home/overdog/Documents/Coding/rawnames.txt","r");
while(-1 != getline(&buffer,&buffer_size,Dictionary))
{
count = count + 1;
for (int i =1; i <= 10; i++)
{
memcpy(buffer2,buffer,buffer_size);
char num[1];
RemoveEndLine(buffer2);
sprintf(num,"%d",i);
strcat(buffer2,num);
printf("%s\n",buffer2);
while(-1 != getline(&buffer3,&buffer_size,Names))
{
memcpy(buffer4,buffer2,buffer_size);
printf("before break\n");
strcat(buffer4,buffer3);
printf("%s",buffer4);
}
}
}
printf("Lines = %d \n",count);
free(buffer);
free(buffer2);
free(buffer3);
free(buffer4);
fclose(Dictionary);
fclose(Names);
printf("test\n");
}
The output seems OK, and the print of "test" at the end of the code prints. And then the Stack smashing error is seen.
Lets take a close look at these two lines:
char num[1];
...
sprintf(num,"%d",i);
You declare num as an array of a single character, forgetting that (char) strings in C are really called null terminated byte strings. That means a string of a single character needs space for two char elements, to fit the terminator.
Since you don't have space for the terminator then sprintf will write out of bounds of your array, leading to undefined behavior and your smashed stack.
If you are certain that the number will never be more than a single digit (which it wont, it will include the two-digit number 10), then you need to have an array of at least two character elements.
I also recommend you use snprintf to avoid buffer overflows like that.
thanks for all the help, what Some Programmer Dude said did help i think but i still had an issue. I found that the issue was the line
strcat(buffer4,buffer3);
As the buffer size for both was the same, it was creating a string which requires a buffer of 80?
i amended the line
char *buffer4 =malloc(buffer_size * sizeof(char));
to read
char *buffer4 =malloc(80 * sizeof(char));
And this now works without stack smashing
Thanks!
Related
I have a notepad file with approximately 150,000 words (representing a dictionary). I'm trying to scan in each word and print it to the console. This setup works fine:
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char* words = (char*)malloc(20 * sizeof(char));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words);
printf("%s\n", words);
}
}
However, this code obviously overwrites "words" each time it loops. I'm trying to get each word to save to a certain array element. I did the following but it instantly crashes (I changed the memory allocation to 2D because I read around here and it seems that is what I am supposed to do):
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char** words = (char**)malloc(20 * sizeof(char*));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words[i]);
printf("%s\n", words[i]);
}
}
Any help is appreciated. I've read around on many posts but haven't figured it out.
In your second version, you allocate space for 20 pointers, but you leave those pointers uninitialized and without anything to point to. I'm sure you can imagine how that presents a problem when you then try to read from your dictionary into the memory designated by one of those pointers.
It looks like you want to allocate space for numwords pointers
char** words = malloc(numwords * sizeof(*words));
, and for each of them, to allocate space for a word.
for(i = 0; i < numWords; i++) {
words[i] = malloc(20); // by definition, sizeof(char) == 1
// ...
Additionally, do check the return value of malloc(), which will be NULL in the event of allocation failure.
The first problem is you only allocated space for a list of words (ie. character pointers) but you didn't allocate space for the words themselves.
char** words = (char**)malloc(20 * sizeof(char*));
This allocates space for 20 character pointers and assigns it to words. Now words[i] has space for a character pointer but not for the characters.
words[i] contains garbage, because malloc does not initialize memory. When you pass it into fscanf, fscanf tries to use the garbage in words[i] as a memory location to write characters to. That's either going to corrupt some memory in the program, or more likely it tries to read a memory location is isn't allowed to and crashes. Either way, it's not good.
You have to allocate memory for the string, pass that to fscanf, and finally put that string into words[i].
char** words = malloc(numWords * sizeof(char*));
for(i = 0; i < numWords; i++) {
char *word = malloc(40 * sizeof(char));
fscanf(ifp, "%39s", word);
words[i] = word;
printf("%s\n", words[i]);
}
Note that I didn't cast the result of malloc, that's generally considered unnecessary.
Also note that I allocated space for numWords in the list. Your original only allocates space for 20 words, once it goes over that it'll start overwriting allocated memory and probably crash. As a rule of thumb, avoid constant memory allocations. Get used to dynamic memory allocation as quickly as you can.
Also note that I limited how many characters fscanf is allowed to read to the size of my buffer (minus one because of the null byte at the end of strings). Otherwise if your word list contained "Pneumonoultramicroscopicsilicovolcanoconiosis", 45 characters, it would overrun the word buffer and start scribbling on adjacent elements and that would be bad.
This leads to a new problem that are common to fscanf and scanf: partial reads. When the code above encounters "Pneumonoultramicroscopicsilicovolcanoconiosis" fscanf(ifp, "%39s", word); will read in the first 39 characters, "Pneumonoultramicroscopicsilicovolcanoco" and stop. The next call to fscanf will read "niosis". You'll store and print them as if they were two words. That's no good.
You could solve this by making the word buffer bigger, but now most words will be wasting a lot of memory.
scanf and fscanf have a whole lot of problems and are best avoided. Instead, it's best to read entire lines and parse them with sscanf. In this case you don't need to do any parsing, they're just strings, so getting the line will suffice.
fgets is the usual way to read a line, but that also requires that you try and guess how much memory you'll need to read in the line. To mitigate that, have a large line buffer, and copy the words out of it.
void strip_newline( char* string ) {
size_t len = strlen(string);
if( string[len-1] == '\n' ) {
string[len-1] = '\0';
}
}
...
int i;
/* The word list */
char** words = malloc(numWords * sizeof(char*));
/* The line buffer */
char *line = malloc(1024 * sizeof(char*));
for(i = 0; i < numWords; i++) {
/* Read into the line buffer */
fgets(line, 1024, ifp);
/* Strip the newline off, fgets() doesn't do that */
strip_newline(line);
/* Copy the line into words */
words[i] = strdup(line);
printf("%s\n", words[i]);
}
strdup won't copy all 1024 bytes, just enough for the word. This will result in using only the memory you need.
Making assumptions about files, like that they'll have a certain number of lines, is a recipe for problems. Even if the file says it contains a certain number of lines you should still verify that. Otherwise you'll get bizarre errors as you try to read past the end of the file. In this case, if the file has less than numWords it'll try to read garbage and probably crash. Instead, you should read the file until there's no more lines.
Normally this is done by checking the return value of fgets in a while loop.
int i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
words[i] = strdup(line);
printf("%s\n", words[i]);
}
This brings up a new problem, how do we know how big to make words? You don't. This brings us to growing and reallocating memory. This answer is getting very long, so I'll just sketch it.
char **readDictionary(FILE *ifp) {
/* Allocate a decent initial size for the list */
size_t list_size = 256;
char** words = malloc(list_size * sizeof(char*));
char *line = malloc(1024 * sizeof(char*));
size_t i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
/* If we're about to overflow the list, double its size */
if( i > list_size - 1 ) {
list_size *= 2;
words = realloc( words, list_size * sizeof(char*));
}
words[i] = strdup(line);
}
/* Null terminate the list so readers know when to stop */
words[i] = NULL;
return words;
}
int main() {
FILE *fp = fopen("/usr/share/dict/words", "r");
char **words = readDictionary(fp);
for( int i = 0; words[i] != NULL; i++ ) {
printf("%s\n", words[i]);
}
}
Now the list will start at size 256 and grow as needed. Doubling grows pretty fast without wasting too much memory. My /usr/share/dict/words has 235886 lines in it. That can be stored in 218 or 262144. 256 is 28 so it only requires 10 expensive calls to realloc to grow to the necessary size.
I've changed it to return the list, because there isn't much good in building the list if you're just going to use it immediately. This allows me to demonstrate another technique in working with dynamically sized lists, null termination. The last element in the list is set to NULL so anyone reading the list knows when to stop. This is safer and simpler than trying to pass the length around with the list.
That was a lot, but that's all the basic stuff you need to do when working with files in C. It's good to do it manually, but fortunately there are libraries out there which make doing this sort of thing a lot easier. For example, Gnome Lib provides a lot of basic functionality including arrays of pointers that automatically grow as needed.
I am trying to read lines from a file into a pointer to a character array using fscanf. I am getting segmentation faults when I print. What am I doing wrong? Should I be using a function other than fscanf?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
#define MAXSTACK 100
#define MAXLENGHT 100
void main(int argc, char * argv[]){
char *filename;
FILE *fp;
char *lines[MAXSTACK];
char * command;
int top = 0;
int numlines = 0;
if(argc < 3){
fprintf(stderr,"error: Not enough arguments provided\n");
exit(1);
}
filename = argv[1];
command = argv[2];
if ( (fp = fopen(filename,"r")) == NULL ){
fprintf(stderr,"error: Cannot open file %s\n",filename);
exit(1);
}
else{
for(int i = 0; i < 3; i++){
fscanf(fp,"%s",lines[i]);
// printf("%s\n",lines[i]);
}
char **ptr2 = lines;
for (int i = 0; i < 2; i++){
printf("%s\n", ptr2[i]);
}
if (strcmp(command,"pop")==0){
//pop(lines);
}else if (strcmp(command,"print_top")==0){
//print_top();
}else if(strcmp(command,"swap_top")==0){
}
}
}
You may want to read lines using fgets:
/* Read a single line into a temporary buffer */
char lineBuffer[MAX_LINE_LENGTH];
while (fgets(lineBuffer, sizeof(lineBuffer), fp) != NULL) {
/* Process the read line */
}
Once you have read a line in the temporary buffer, you can deep-copy the read string into some memory that you allocated on the heap using malloc (or you can just use strdup), and then you can store a pointer to that memory into your lines array:
/* Inside the body of the while loop */
/*
* Deep copy current line into the string pointer array.
* strdup = malloc + strcpy
* Note that free is required to release memory!
*/
lines[currLineIndex] = strdup(lineBuffer);
currLineIndex++;
Note that when you write code like this:
char *lines[MAXSTACK];
you are allocating on the stack an array of MAXSTACK items, each item being a char* pointer. But then you have to give some meaningful value to those pointers (for example: allocating some memory from the heap and pointing to that memory).
Of course, when you are done, you have to scan the whole array and call free on each element pointer to avoid memory leaks.
Moreover, a good coding practice would be to clear the pointers in the array before using it, e.g.:
memset(lines, 0, sizeof(lines));
fscanf("%s", lines[i]) will read a sequence of non-white-space characters (note, not a whole line) into the memory pointed to by lines[i]. The problem is, that you haven't set lines[i] to point to any memory and that is why you get the segfault, you're asking for a sequence of characters to be copied to some undefined location.
If you replace your declaration of an array of character pointers, char *lines[MAXSTACK];, with a declaration of an array of arrays of characters char lines[MAXLENGTH][MAXSTACK] then lines[i] will be an array of MAXLENGTH characters which fscanf("%s", lines[i]) which be able to copy to without seg faulting.
The question remains now, what happens if the string fscanf tries to read is longer than MAXLENGTH? The answer is more characters will be read than can fit into the lines[MAXLENGTH] array and you get what is called a buffer overflow. To safeguard against this you can limit the maximum number of characters fscanf will read from a string, to 100 for example, with fscanf("%100s", lines[i])
My assignment is to read words from a text file and store them in character arrays which are stored in an array of char*. All memory in these arrays needs to be dynamically allocated.
What I am doing is reading in each word with fscanf() and storing it into the variable str. I am then calculating the length of the word in str and dynamically allocating memory to store the value of str in the character array new_word. new_word is then inserted into the array of char* named words. When words runs out of space, I double its size and continue.
My problem lies in the commented code starting on line 62. I'm going to need to read these words later from words, so I'm testing my ability to access the pointers and their values. I can index new_word fine (in the lines above), but when I then store new_word in words and try to read from words, I get the following error:
hw1.c:63:25: error: subscripted value is not an array, pointer, or vector
while (*(words[count])[k] != '\0'){
on lines 63 and 64. I know it has something to do with dereferencing the pointer, but I have tried a bunch of variations with no success. How can I fix this?
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]){
if (argc != 3){
fprintf(stderr, "Incorrect number of arguments\n");
exit(1);
}
char* infile = argv[1];
FILE* finp = fopen(infile, "r");
if (finp == NULL){
fprintf(stderr, "Unable to open input file\n");
exit(1);
}
char* prefix = argv[2];
int count = 0;
int size = 20;
char* words = calloc(size, sizeof(char));
printf("Allocated initial array of 20 character pointers.\n");
char* str = malloc(30*sizeof(char));
while (fscanf(finp, "%s", str) == 1){
if (count == size){
words = realloc(words, 2 * size);
size *= 2;
printf("Reallocated array of %d character pointers.\n", size);
}
int i = 0;
while (str[i] != '\0'){
i++;
}
char* new_word = malloc((i+1)*sizeof(char));
int j = 0;
while (str[j] != '\0'){
new_word[j] = str[j];
j++;
}
new_word[j] = '\0';
int k = 0;
while (new_word[k] != '\0'){
printf("%c", new_word[k]);
k++;
}
printf("\n");
words[count] = *new_word;
/*k = 0;
while (*(words[count])[k] != '\0'){
printf("%c", *(words[count])[k]);
k++;
}
printf("\n");*/
count++;
}
}
Ok, dissecting that a bit:
char* words = calloc(size, sizeof(char));
this should probably read:
char **words = calloc(size, sizeof(char *));
Why? What you want here is a pointer to an array of pointers to char ... words points to the first char *, which points to your first "string".
char* str = malloc(30*sizeof(char));
while (fscanf(finp, "%s", str) == 1){
Buffer overflow here. Make sure to read at maximum 30 characters if you define your buffer not to hold more. Btw, just for convention, call your buffer buffer or buf (not str) and there's really no need to dynamically allocate it. Hint: Use a field size for fscanf() or, even better, some other function like fgets().
if (count == size){
words = realloc(words, 2 * size);
size *= 2;
printf("Reallocated array of %d character pointers.\n", size);
}
The realloc here will not work, should read
words = realloc(words, 2 * size * sizeof(char *));
You need to multiply the size of a single element, which, in this case, is a pointer to char.
No guarantee this will be all errors, but probably the most important ones. On a sidenote, strlen() and strncpy() will help you stop writing unnecessary code.
A pointer to "A [dynamically-allocated] array of char*" would need to be recorded in a variable of type char **. That is, a pointer to the first element of the array, which element is of type char *. Thus ...
char **words;
If you want to have sufficient space for size words, then you could allocate it as ...
words = calloc(size, sizeof(char *));
(note the difference from your code), though it's harder to make a mistake with this form:
words = calloc(size, sizeof(*words));
Note in that case that the sizeof operator does not evaluate its operand, so it does not matter that words is not yet allocated.
Most importantly, be aware that the elements of array words are themselves pointers, not the ultimately pointed-to strings. Thus you assign a new word to the array by
words[count] = new_word;
(Again, note the difference from your version.) Other adjustments are needed as well.
The problematic while loop, though, is not fixed even then. Remember that the expression pointer[index] is equivalent to *((pointer) + (index)), so the expression *(words[count])[k] attempts to triply derference words. Even with the type correction, you want only to doubly dereference it: words[count][k].
But why re-invent the wheel? As Olaf observed with respect to strlen() and some of your earlier code, C already has perfectly good functions in its standard library for dealing with strings. In this case ...
printf("%s", words[count]);
... would be so much simpler than that while loop.
I am currently getting the following error
Process terminated with status -1073741819
and I suspect its my fgets() but I have no idea why this is happening, any help would be much appreciated.
//Gets Dictionary from file
char* GetDictionary() {
int ArraySize;
int i = 0;
FILE * DictionaryFile;
//Gets first line (in this case it is the amount of Lines)
DictionaryFile = fopen("dictionary.txt", "r");
fscanf(DictionaryFile,"%d", &ArraySize);
ArraySize = ArraySize + 1;
printf("%d", ArraySize);
fclose(DictionaryFile);
//Gets the array
char* Dictionary = malloc(sizeof(char)*ArraySize);
char Temp[ArraySize];
char TempArray[ArraySize];
DictionaryFile = fopen("dictionary.txt", "r");
while(fgets(Temp, sizeof Temp, DictionaryFile)!=NULL) {
Dictionary[i] = Temp;
//Check The array
printf("%s", Dictionary[i]);
i++;
}
fclose(DictionaryFile);
return Dictionary;
}
-1073741819 --> C0000005 and likely has some significance. Maybe use below to discern its meaning.
puts(strerror(-1073741819));
Code has many issues: Here are some corrected to get you going.
1) Allocate an array of pointers, not an array of char
// char* Dictionary = malloc(sizeof(char)*ArraySize);
char** Dictionary = malloc(ArraySize * sizeof *Dictionary);
2) Form a big buffer to read each line
char Temp[100];
3) After reading each line, get rid of the likely trailing '\n'
size_t len = strlen(Temp);
if (len && Temp[len-1] == '\n') Temp[--len] = 0;
4) Allocate memory for that word and save
Dictionary[i] = malloc(len + 1);
assert(Dictionary[i]);
memcpy(Dictionary[i], Temp, len + 1);
5) Robust code frees it allocations before completion
6) Code reads "amount of Lines" twice as file is opened twice. Just leave file open (and not re-open it). #user3386109
You likely want Dictionary to be an array of char strings. That is, Dictionary is an array, and each element in the array is a char *. That makes Dictionary a char **.
For this example, it may be most straightforward to allocate memory for the Dictionary array itself, then allocate memory for its contents. You'll need to free all this when you're done, of course.
char **Dictionary = malloc(sizeof(char *) * ArraySize);
for (int i = 0; i < ArraySize; i++) {
Dictionary[i] = malloc(ArraySize);
}
There are better ways to do this. For one, you might only allocate memory when you need it, for each fgets() return. You could also use strdup() to allocate only the memory you need. You could also pass in Dictionary from the caller, already allocated, so you don't worry about allocating it here.
Later in your program, as #WhozCraig pointed out, you need to copy the string in Temp, like strcpy(Dictionary[i], Temp), in place of Dictionary[i] = Temp. I too am surprised that's not generating a compiler warning!
The task of this function is fairly straightforward. Given an array of char*, a pointer to a file, and a maximum word size, it reads through the file and copies each word one by one into the char* array. Since there's one word per line in the file, it makes sense to use \n as the break between words. So with that in mind, the code should be fairly simple to interpret:
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
int nNameCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
//allocate space for a word
strCurrent = malloc(nMaxLetters * sizeof(char));
while ((cCurrent = fgetc(filePointer)) != EOF) {
if(cCurrent != '\n')
{
strCurrent[nCursor] = cCurrent;
nCursor++;
} else { //then we've reached the end of the line (word)
//add null termination to string
strCurrent[nCursor] = '\0'; //SEG FAULT
//copy string to dictionary
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
//increment count
nNameCount++;
//reset the cursor
nCursor = 0;
}
}
}
This code generates a segmentation fault at the line where I call strCurrent[nCursor] = '\0';. I'm not sure why, because on the face of it, it seems like this operation should be no different from the operation in the other block, where I call strCurrent[nCursor] = cCurrent;. strCurrent should have allocated more than enough space to store all necessary characters. So, I'm somewhat at a loss. Help me figure this one out, guys.
Note: I think I would probably have an easier time using fgets instead of fgetc to accomplish this task. I might well switch to that; however, since I have encountered an error I don't understand, I don't want to leave it alone until I've understood it.
EDIT:
Someone pointed out that the error might occur in the memcpy operation, possibly due to strDictionary being improperly allocated. Here's the main block where strDictionary gets allocated. Perhaps I have made an error:
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//obtain the number of lines and the maximum word size of the dictionary
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate memory for strDictionary
strDictionary = malloc(nNumLines * nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//Output here correctly prints: 1000 and 21
//reset the file pointer (not sure if this is a necessary step, but oh well)
filePointer = fopen("dictionary.txt", "r");
//load dictionary into memory
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}
EDIT 2:
OK, I decided to use fgets() instead of fgetc() to greatly simplify my function. I've also done what I thought was a correct malloc() operation for strDictionary. However, I'm still getting a seg fault. Here's the updated code:
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
printf("Call to loadDictionary. nMaxLetters = %d\n", nMaxLetters);
int nWordCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
strCurrent = malloc(nMaxLetters); //allocate space for a word
while (fgets(strCurrent, nMaxLetters, filePointer) != NULL)
{
memcpy(strDictionary[nWordCount], strCurrent, strlen(strCurrent)+1);
nWordCount++;
}
}
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//count the lines in the file (works fine)
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate space for the dictionary
strDictionary = malloc(nNumLines * sizeof(char*));
for (i = 0; i<nLines; i++)
strDictionary[i] = malloc(nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//load dictionary into array
filePointer = fopen("dictionary.txt", "r");
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}
Here:
char cCurrent;
...
while ((cCurrent = fgetc(filePointer)) != EOF) {
You are truncating the fgetc()'s value of type int to char. This may lead to the while condition not correctly recognizing EOF. cCurrent has to be int.
Here:
//allocate space for a word
strCurrent = malloc(nMaxLetters * sizeof(char));
nMaxLetters has to account for one extra character representing the string NUL terminator. Is it accounted for?
Btw, sizeof(char) is always 1.
Now, this parameter declaration:
char* strDictionary[]
is equivalent to this:
char** strDictionary
or, IOW, a pointer to a pointer to a char. That's because in C, arrays are never passed as parameters, only pointers to their first elements are, despite the deceptive syntax with the brackets suggesting something is an array.
This line:
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
is going to take nNameCount'th pointer to a char and write character data where it points to.
But does the calling function allocate at least as many string buffers (of length nMaxLetters) as there are going to be lines in the file? Does it populate some array of pointers to char with the pointers to these buffers before passing this array into loadDictionary()? IOW, this code is expecting the caller to do something like this:
#define nMaxEntries 1000
char* dictionary[nMaxEntries];
int i;
FILE* f;
...
for (i = 0; i < nMaxEntries; i++)
dictionary[i] = malloc(nMaxLetters);
loadDictionary(dictionary, f, nMaxLetters);
Memory allocation failures must be checked in the above code. Also, I'd strongly suggest passing nMaxEntries into or using it in loadDictionary() so you don't overrun the array of pointers if the file has more lines than nMaxEntries. nNameCount should not grow beyond nMaxEntries.
UPDATE to the updated question...
Here:
char** strDictionary;
...
strDictionary = malloc(nNumLines * nMaxChars * sizeof(char));
You are not creating an array of pointers to char as loadDictionary() expects per the above analysis, you are creating a 2d array of char. And because of that the segfault most probably occurs not on this line:
strCurrent[nCursor] = '\0'; //SEG FAULT
but on the very next one, which may not be apparent in the debugger until you zoom in and look at the disassembly of the code:
//copy string to dictionary
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
UPDATE2:
I don't understand why you now allocate space for nNumLines pointers:
strDictionary = malloc(nNumLines * sizeof(char*));
but of those nNumLines pointers you initialize nLines pointers (and nLines never becomes anything other than 0 if I'm reading your latest code correctly):
for (i = 0; i<nLines; i++)
strDictionary[i] = malloc(nMaxChars * sizeof(char));
What's the trick? Typo?