Debugging beginner C crash, looking for alternate logic with bug found - c

I was doing a study on a program which is working (mostly) and... I ran into a bug that causes a complete crash in the system at the finish line. After print-screening to pinpoint the leak, I'm reasonably sure I've found the gremlin in it's hiding spot, but I can't think of any bug spray solution to this!
Would any of you have ideas or advice on solving this puzzle? I think a fresh pair of eyes would do wonders! I definitely appreciate your time, I'm pretty sure it's really something simple at the end of it all! >_<
Thank you for any comment or suggestions!
Information about the program + script:
Take any number of user-input (numbers only) strings
When user inputs an empty string, the program will detect that as the end of user inputs, and proceed with wrapping things up.
tokenize and convert each token to integers.
Add the ints into dynamically allocated database.
Here are anomalies I found
Main_Size always has a final result 1 above what it should be.
The error likely stems from the loop() function I created. Normally when a user inputs an empty string, that should be the end of it. But the program seems to count that empty string and ship it off into the assembly, where a NULL value eventually gets housed into the main int-array. I'm almost 100% positive that's where my error is. I've tried multiple different ways to detecting a null string and avoid sending that to the rest of assembly, but no luck so far :(
The aggressive print-debugging I used seems to "break formation" at the final round of printing a single string. There's an additional line break, and I have no idea how it got there.
Using a scanf prompt to signal end of user-input strings yields good results, but the moment more than one string are entered before the end, the program goes haywire.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 12
#define MIN_SIZE 2
int loop(int* Main_Array, char str[], int Main_Size);
int* Create_Main_Array();
int Input_String(char str[]);
int Token_Atoi(char str[], int numElements, int* Main_Array, int Main_Size);
int Dynamic_Fitting(int* Main_Array , int Incomming_int , int Main_Size);
void Free_All(int* Main_Array);
////////////////////
/////////////////////////////////////////////////
int main()
{
char str[MAX_SIZE];
int* Main_Array = Create_Main_Array(), Main_Size = 0;
//Main_Size = The number of elements currently in the dynamic memory.
//This number should increase by 1 for every new int you add into the
//array, starting from zero, as in Main_Array[0] = ####
Main_Size = loop(Main_Array, str, Main_Size);
printf("\n\nMain_Size final size is: %i\n", Main_Size);
for(int i=0; i<Main_Size; i++)
printf("Check: %i \n", Main_Array[i]);
Free_All(Main_Array);
system("PAUSE");
return 0;
}
/////////////////////////////////////////////////
//Sets up Dynamic Space. It will be realloced in the future.
/////////////////////////////////////////////////
int* Create_Main_Array()
{
return (int*)malloc(MAX_SIZE*sizeof(int));
}
/////////////////////////////////////////////////
//Calls up the user to input a string.
//Loops the entire process so long as returned string is larger then 0.
//Returns total Element size of Main, after it's been modified in the program.
/////////////////////////////////////////////////
int loop(int* Main_Array, char str[], int Main_Size)
{
int numElements;
while(numElements>0)
{
numElements = Input_String(str);
//for some reason, at the very end of the loop, it will tag on another '\0'
//into the Main_Array, which causes a crash. Likely the setup at line 52.
Main_Size = Token_Atoi(str, numElements, Main_Array, Main_Size);
}
return Main_Size;
}
/////////////////////////////////////////////////
//Enters strings, and returns size of the strings.
//Will not count Line breaks as a character.
//Going under or over a limit will trigger a reroute.
/////////////////////////////////////////////////
int Input_String(char str[])
{
printf("\nPlease input a string of numbers.\n");
printf("Tap enter again once finnished: \n\n");
int i=0;
while ((str[i] = getchar()) != '\n')
i++;
str[i+1]='\0';
return i;
if (i>MAX_SIZE-1 || i<MIN_SIZE)
{
printf("Your sumbition dosn't fit the size criteria.\n");
printf("Please reenter:\n\n");
Input_String(str);
}
}
/////////////////////////////////////////////////
//Tolkenizes string, Atoi each token into cute little ints.
//Each int will be sent to the Dynamic_Fitting to be assimilated into Main_Array
//Main_Size is passed into this function just to be used as parameters for the fitting.
/////////////////////////////////////////////////
int Token_Atoi(char str[], int numElements, int* Main_Array, int Main_Size)
{
char* temp = strtok(str, " -");
int i=0;
while (temp != NULL)
{
printf("String tokenize check: %s\n", temp);
Main_Size = Dynamic_Fitting(Main_Array, atoi(temp), Main_Size);
//Main size should be upgraded with each loop of the above line.
temp = strtok(NULL, " -");
i++;
}
return Main_Size;
}
/////////////////////////////////////////////////
//Will first increase the size of the dynamically allocated array of ints by 1 int
//Then, it will add the incomming int into the re-sized dynamic space.
//Main size serves as a bookmark to show where on the array the new realloc'd spot should be.
/////////////////////////////////////////////////
int Dynamic_Fitting(int* Main_Array , int Incomming_int , int Main_Size)
{
realloc(Main_Array, sizeof(int));
Main_Array[Main_Size]= Incomming_int;
printf("Dynamic fitting check: %i put into Main_Array[%i]\n\n", Incomming_int, Main_Size);
return Main_Size+1;
}
/////////////////////////////////////////////////
//Close shop
/////////////////////////////////////////////////
void Free_All(int* Main_Array)
{
free(Main_Array);
}

The line
realloc(Main_Array, sizeof(int));
is wrong. realloc returns a pointer that may point to new memory so when you dereference Main_Array on the next line you may be accessing freed memory. Also, you need to pass the full size of the updated memory buffer, not just the delta.
You could fix things by changing Dynamic_Fitting to something like
int Dynamic_Fitting(int** Main_Array , int Incomming_int , int Main_Size)
{
int* temp = realloc(Main_Array, (Main_Size +1) * sizeof(int));
if (temp == NULL) {
return -1; /* caller must handle oom error */
}
*Main_Array = temp;
(*Main_Array)[Main_Size] = Incomming_int;
printf("Dynamic fitting check: %i put into Main_Array[%i]\n\n", Incomming_int, Main_Size);
return Main_Size+1;
}
and calling it like
Main_Size = Dynamic_Fitting(&Main_Array, ....);
if (Main_Size == -1) {
/* out of memory. cleanup and exit program */
}

I guess this is one of the issue.
you have shared a very bog code and analysing everything is bit of a task... see if below issue solves your issu..
int Input_String(char str[])
{
printf("\nPlease input a string of numbers.\n");
printf("Tap enter again once finnished: \n\n");
int i=0;
while ((str[i] = getchar()) != '\n') // HERE if user enters more than array Size it will fail... with exception
i++;
str[i+1]='\0';
return i; /// THIS is wrong.. following if will never execute..
if (i>MAX_SIZE-1 || i<MIN_SIZE)
{
printf("Your sumbition dosn't fit the size criteria.\n");
printf("Please reenter:\n\n");
Input_String(str);
}
}
I will suggest below
int Input_String(char str[])
{
printf("\nPlease input a string of numbers.\n");
printf("Tap enter again once finnished: \n\n");
int i=0;
while ((str[i] = getchar()) != '\n') {
i++;
if (i>MAX_SIZE-1 || i<MIN_SIZE)
{
printf("Your sumbition dosn't fit the size criteria.\n");
printf("Please reenter:\n\n");
Input_String(str);
break;
}
}
str[i+1]='\0';
return i;
}

Related

Trying to figure out why my struct pointer is storing data inaccurately

I am trying to improve my C skills so I apologize if my question is long. I am having a hard time understanding as to why my struct pointer holds the wrong value in my program, I tried to debug it but I am still relatively new to C and was hoping one of you could tell me what I'm doing wrong here and how I could improve my code and what to focus on.
I am making a program that stores user data on this struct and then prints it out.
typedef struct table {
char *firstName;
char *lastName;
int id;
}USER;
This function below stores the first name
void firstName(int *counter, int *check, USER *pt) {
for (int i = *counter; i < *check; i++) {
pt[i].firstName = calloc (MAX_LENGTH, sizeof(pt));
printf("Enter First Name: ");
getchar();
fgets(pt[i].firstName, MAX_LENGTH, stdin);
}
}
This is just my bool function returning true or false
bool isTrue(char *decision) {
if(*decision == 'Y') {
return true;
}
else {
return false;
}
}
And this is my main
int main(int argc, char **argv) {
USER *pt = calloc(1, sizeof(pt));
int counter = 0, check = 0;
char decision = '\0';
while (1) {
printf("Would you like to enter a user?(Y/N):");
fgets(&decision, 2, stdin);
strtok(&decision, "\n"); //remove the newline char
if (!isTrue(&decision)) {
break;
}
if (counter != 0) {
pt = realloc(pt, sizeof(pt) * 10); //the 10 is temporary
}
check = counter + 1; // make sure loop only runs once.
firstName(&counter, &check, pt);
++counter; // increment counter;
}
printStruct(pt, &counter);
return 0;
}
When I run it out sometimes it works fine and returns everything and sometimes it skips a value. This is what I get. It skips the value at pointer index 1 and prints garbage instead.
Would you like to enter a user?(Y/N):N
First name at array 0 is Ermir
First name at array 1 is P#1First name at array 2 is Kevin
First name at array 3 is Blaus
First name at array 4 is Adam
Also I was wondering why is it when I realloc here If i do I get a realloc error when I enter the second name.
if (counter != 0) {
pt = realloc(pt, sizeof(pt) * 10); //realloc(pt, sizeof(pt) * counter + 1) wont work
}
char decision = '\0';
...
fgets(&decision, 2, stdin);
You are only allocating 1 char but are at least reading 2 chars into it. Fix by allocating a sufficiently sized array for decision.
Unrelated but in firstName() pt[i].firstName = calloc (MAX_LENGTH, sizeof(pt)); should be pt[i].firstName = calloc (MAX_LENGTH, 1);

Not able to write a string to a *char[]

I've been at this for hours with little progress made. I need to know why exactly my program is crashing when scanf() is called. The error message: "Segmentation fault; core dumped" leads me to believe that I'm not allocating memory to the dynamic array correctly. If this is the case could someone tell me how I can correctly allocate memory to add one struct to the array?
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
enum Subject{
SER = 0, EGR = 1, CSE = 2, EEE = 3
};
struct Course{
enum Subject sub;
int number;
char instructor_name[1024];
int credit_hours;
}*course_collection;
int total_courses = 0;
int total_credits = 0;
void course_insert();
void resizeArray();
int main(int argc, char** argv) {
int choice = 0;
while(choice != 4){
printf("Welcome to ASU, please choose from the menu"
"choices.\n\n");
printf("_____________________________________________\n\n");
printf("Menu:\n 1.Add a class\n 2. Remove a class\n"
" 3.Show classes\n 4.Quit");
printf("\n\nTotal credit hours: %d\n\n", total_credits);
printf("\n\n_________________________________________");
scanf("%d", &choice);
if(choice == 1){
resize_array(total_courses);
course_insert();
}
else if(choice == 3)
print_courses();
}
return (EXIT_SUCCESS);
}
void resize_array(int total_courses) {
course_collection = malloc(total_courses +
sizeof(course_collection));
}
void print_courses() {
int i;
for(int i = 0; i < total_courses; i++){
printf("\nInstructor: %s\n\n",
course_collection[i].instructor_name);
}
}
void course_insert(){
printf("\n\nEnter the instructor's name\n\n");
scanf("%s" , course_collection[total_courses].instructor_name);
total_courses++;
}
//will crash just after scanf();
//must press 1 & enter for correct output
After entering a few instructor names I choose the third option from the menu and that should iterate through the array and print each instructor's name but all I get are blanks lines and the last instructor name I imputed.
UPDATE
#user3545894 I've tried this and it seems to work fine but I still get the issue with the output not being correct. I should be able to iterate through the array and print the strings in each subscript.
The problem came from malloc(total_courses + sizeof(course_collection))
You only allocate array of pointer of course_collection.
You need allocate memory for whole the struct Course
It should be malloc(total_courses * sizeof(struct Course))
User this malloc(total_courses + sizeof(struct Course)) instead of malloc(total_courses + sizeof(course_collection))
segmentation fault due to memory allocation mostly for arrays
arr[n] we use it till '0' to 'n-1' { carefully observe not 'n'}

Getting stuck in Dictionary Project in C

I prefer to create a Dictionary object and add 3 words to it.
My program has no compilation error but gets a run time error in the second for loop, is the problem in addNewWord function? Do I need pass a pointer to the DictionaryWord object ?
Please help me.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
char* name;
char* mean;
} Words;
typedef struct{
Words* word;
int size;
} Dictionary;
Dictionary createNewDictionary();
Words createNewWord();
void addNewWord(Words newword, Dictionary dic);
Dictionary createNewDictionary(){
Dictionary dic;
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
return dic;
}
Words createNewWord(){
Words newword;
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", newword.name);
fflush(stdin);
printf("\nEnter meaning: ");
scanf("%[^\n]", newword.mean);
return newword;
}
void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
}
int main(){
Dictionary d = createNewDictionary();
for (int i=0;i<3;i++){
addNewWord(createNewWord(), d);
}
return 0;
}
There are lots of problem with your code:
Given the longest word in English is around 30 characters, this size allocation is realistic for the word, but not for the defintion:
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
This makes little obvious sense:
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
you called malloc() on zero! You're only spared by your later realloc(). Even if intentional, it really deserves a comment.
This doesn't really work as fflush() is for output streams:
fflush(stdin);
see: How to clear input buffer in C? And whatever fix you use has to apply to both scanf() calls, not just one!
Per #Jarvis, this doesn't work:
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
as you didn't allocate any space for name and mean in dic so you're copying into random memory.
Per #Jarvis, doesn't work:
void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
You're passing dic by value so inside addnewWord() you've a copy of dic so the original dic's size will be the same as it was before the call!
Memory leak:
addNewWord(createNewWord(), d);
you dropped your handle onto what createNewWord() returned so you can never free the memory it malloc()'d
You malloc() memory but provide no means to eventually free it.
Passing and returning structs by value is a disaster in a situation like this, as the data keeps getting copied. At the least it's inefficient, at worst its buggy like the size issue above. Rather than risk it, pretend they can only be passed and returned by pointer and you'll be playing it safe and get a better result.
Below is a rework of your code (in C) with fixes, style tweaks and an attempt at a consistent terminology. It also provides some minimal test code and the ability to free your data:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LENGTH 30
#define MAX_DEFINITION_LENGTH 1024
typedef struct entry {
char *word;
char *definition;
} Entry;
typedef struct dictionary {
Entry *entries;
int num_entries, max_entries;
} Dictionary;
Dictionary *createNewDictionary() {
Dictionary *dictionary = malloc(sizeof(*dictionary));
dictionary->num_entries = 0;
dictionary->max_entries = 1;
dictionary->entries = calloc(dictionary->max_entries, sizeof(*dictionary->entries));
return dictionary;
}
void freeEntry(Entry *entry) {
free(entry->word);
free(entry->definition);
free(entry);
}
void freeDictionary(Dictionary *dictionary) {
for (--dictionary->num_entries; dictionary->num_entries >= 0; --dictionary->num_entries) {
// we can't call freeWord() here -- why.
free(dictionary->entries[dictionary->num_entries].word);
free(dictionary->entries[dictionary->num_entries].definition);
}
free(dictionary->entries);
free(dictionary);
}
void purgeInput() {
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
Entry *requestNewEntry() {
Entry *entry = malloc(sizeof(*entry));
entry->word = malloc(MAX_WORD_LENGTH);
entry->definition = malloc(MAX_DEFINITION_LENGTH);
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", entry->word);
purgeInput();
printf("\nEnter definition: ");
scanf("%[^\n]", entry->definition);
purgeInput();
return entry;
}
void addNewEntry(Entry *entry, Dictionary *dictionary) {
if (dictionary->num_entries == dictionary->max_entries) {
dictionary->max_entries *= 2;
dictionary->entries = realloc(dictionary->entries, dictionary->max_entries * sizeof(*dictionary->entries));
// check if realloc returns NULL and if so, handle the error.
}
dictionary->entries[dictionary->num_entries].word = strdup(entry->word);
dictionary->entries[dictionary->num_entries].definition = strdup(entry->definition);
dictionary->num_entries++;
}
int main() {
Dictionary *d = createNewDictionary();
for (int i = 0; i < 3; i++) {
Entry *e = requestNewEntry();
addNewEntry(e, d);
freeEntry(e);
}
printf("\nRead: ");
for (int i = 0; i < d->num_entries; i++) {
printf("%s (%lu chars) ", d->entries[i].word, strlen(d->entries[i].definition));
}
printf("\n");
freeDictionary(d);
return 0;
}
CREATING A PUN DICTIONARY
> ./a.out
============================
Enter word: silkworm
Enter definition: Two silkworms had a race but ended up in a tie.
============================
Enter word: horse
Enter definition: A horse is a stable animal.
============================
Enter word: termite
Enter definition: A termite walks into a pub and asks, "Is the bar tender here?"
Read: silkworm (47 chars) horse (27 chars) termite (62 chars)
>
I see what's wrong with your code. First of all, you need to pass your Dictionary object by pointer to the function, addNewWord, and in the function addNewWord, you again need to allocate memory to each of the char* fields, name and mean, of the dic object. Here is the corrected code :
void addNewWord(Words newword, Dictionary *dic){
dic->size++;
dic->word = (Words*)realloc(dic->word, dic->size*sizeof(Words));
dic->word[dic->size-1].name = (char*)malloc(30*sizeof(char)); //added
dic->word[dic->size-1].mean = (char*)malloc(30*sizeof(char)); //added
strcpy(dic->word[dic->size-1].name, newword.name);
strcpy(dic->word[dic->size-1].mean, newword.mean);
}
Pass the dictionary's address as :
addNewWord(createNewWord(), &d);
and change the definition as well as prototype of the function as well :
void addNewWord(Words newword, Dictionary *dic)
Find the complete code here : http://pastebin.com/ZN69hevj

How to add/remove a string in a dynamic array in c language

I have a defined array sample:
char *arguments[] = {"test-1","test-2","test-3"};
I am trying to add an argument input given by the command line. I tried the strcpy function and also to pass it through the array element e.g. arguments[num+1] = argv[1] but again not successfully.
I know that this is a very simple question but I am not an experienced programmer and all my experience comes from higher level programming languages (PHP, Perl).
The closest sample of work that I found online is C program to insert an element in an array and C program to delete an element from an array. But are not exactly what I am looking for and they are working with intigers not characters that I need.
My goal is to find a way to add and remove strings from a dynamic array that can grow and shrink based on the process of the script.
Thanks everyone for their time and effort to assist me.
Sample of a working code is given under:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Set as minimum parameters 2 */
#define MIN_REQUIRED 2
#define MAX_CHARACTERS 46
/* Usage Instructions */
int help() {
printf("Usage: test.c [-s <arg0>]\n");
printf("\t-s: a string program name <arg0>\n");
printf("\t-s: a string sample name <arg1>\n");
return (1);
}
int main(int argc, char *argv[]) {
if ( argc < MIN_REQUIRED ) {
printf ("Please follow the instructions: not less than %i argument inputs\n",MIN_REQUIRED);
return help();
}
else if ( argc > MIN_REQUIRED ) {
printf ("Please follow the instructions: not more than %i argument inputs\n",MIN_REQUIRED);
return help();
}
else {
int size, realsize;
char *input = NULL;
char *arguments[] = {"test-1","test-2","test-3"};
int num = sizeof(arguments) / sizeof(arguments[0]);
printf("This is the number of elements before: %i\n",num);
int i;
for (i=0; i<num; i++) {
printf("This is the arguments before: [%i]: %s\n",i,arguments[i]);
}
printf("This is the input argument: %s\n",argv[1]);
printf("This is the array element: %i\n",num+1);
input = (char *)malloc(MAX_CHARACTERS);
if (input == NULL) {
printf("malloc_in failled\n");
exit(0);
}
memset ( input , '\0' , MAX_CHARACTERS);
int length_before = strlen(input);
printf("This is the length before: %i\n",length_before);
strcpy(input , argv[1]);
int length_after = strlen(input);
printf("This is the length after: %i\n",length_after);
//arguments[num+1] = input;
strcpy(arguments[num+1],input);
int num_2 = sizeof(arguments) / sizeof(arguments[0]);
printf("This is the number of elements after: %i\n",num);
for (i=0; i<num_2; i++) {
printf("This is the arguments after [%i]: %s\n",i,arguments[i]);
}
} // End of else condition
return 0;
} // Enf of int main ()
"My goal is to find a way to add and remove strings from a dynamic array":
char *arguments[] = {...} is statically allocated, so it cannot serve as a "dynamic array".
strcpy(arguments[num+1],input):
You cannot access arguments[num+1] when this array has only num entries.
Suggested fix - allocate and initialize arguments dynamically, according to the value of argc:
char* strings[] = {"test-1","test-2","test-3"};
int i, num = sizeof(strings) / sizeof(*strings);
char** arguments = malloc((num+argc-1)*sizeof(char*));
if (arguments == NULL)
; // Exit with a failure
for (i=0; i<num; i++)
{
arguments[i] = malloc(strlen(strings[i])+1);
if (arguments[i] == NULL)
; // Deallocate what's already been allocated, and exit with a failure
strcpy(arguments[i],strings[i]);
}
for (i=0; i<argc-1; i++)
{
arguments[num+i] = malloc(strlen(argv[i+1])+1);
if (arguments[num+i] == NULL)
; // Deallocate what's already been allocated, and exit with a failure
strcpy(arguments[num+i],argv[i+1]);
}
...
// Deallocate everything before ending the program
There are no dynamic arrays in C, arguments has a static size, capable of holding 3 elements,
strcpy(arguments[num+1],input);
is simply undefined behaviour, the expression arguments[num+1] accesses an array out of bounds (two elements after the last); no magical reallocation or something will happen.
In general, you have three options:
You have an upper bound of how many items you want to be able to store in the array and declare the array to have that size. Either keep track of the numbers actually stored in it or add some sentinel value (which needs additional space!) indicating the end.
You have an upper bound, and if the number of items you want to store happen to exceed this limit, you abort (returning an error indicator, telling the user that the input data is too big, …).
Look for malloc, realloc and free.

What in my program is causing exception c0000005? (Probably a memory error)

My code:
#include <stdio.h>
#include <stdint-gcc.h>
#include <string.h>
int checkAnagram(char *word1, char *word2, int length){ //This function compares the two strings by storing the occurrences of their letters in a histogram, and then comparing that histogram.
printf("test4");
int i, n;
int letterCount1[26], letterCount2[26];
char letter;
for(i=0;i<length;i++){
letter = word1[i];
letterCount1[letter-'a']++;
}
for(n=0;n<length;n++){
letter = word2[n];
letterCount2[letter-'a']++;
}
for(i=0;i<26;i++){
for(n=0;n<26;n++){
if(letterCount1[i]==letterCount2[n]){
i++;
} else {
return 0;}
}
}
return 1;
}
void main(){
int length1, length2,i,n;
scanf("%d", &length1);
int lengthArray1[length1]; //Array used to store the length of each string (without white spaces)
char *sentenceArray1[length1];
char tempString[100000];
//The array for storing the first set of sentences, and a temporary string used
//for allocating memory in the next loop
for(i=0;i<=length1;i++){
fgets(tempString, 100000, stdin); //Reads the first line of input (up to and including \0), with a maximum line length which will probably be sufficient.
sentenceArray1[i]=malloc((strlen(tempString))*sizeof(char)); //Allocates just enough memory for each string (including \0).
int index = 0;
for(n=0;n<(strlen(tempString));n++){
if(tempString[n] != ' ' && tempString[n] != '.') { //Copies only from the input if the character is not a whitespace.
sentenceArray1[i][index++]=tolower(tempString[n]);
}
}
sentenceArray1[i][index] = '\0';
lengthArray1[i]=strlen(sentenceArray1[i]);
printf("test1\n");
}
scanf("%d", &length2);//Same stuff as above, now for the second set of strings.
int lengthArray2[length2], index;
char *sentenceArray2[length2];
for(i=0;i<=length2;i++){
fgets(tempString, 100000, stdin);
sentenceArray2[i]=malloc((strlen(tempString))*sizeof(char));
index = 0;
for(n=0;n<(strlen(tempString));n++){
if(tempString[n] != ' ' && tempString[n] != '.') {
sentenceArray2[i][index++]=tolower(tempString[n]);
}
}
sentenceArray2[i][index] = '\0';
lengthArray2[i]=strlen(sentenceArray2[i]);
printf("test2\n");
}
printf("test3");
for(i=0;i<length1;i++){
for(n=0;n<length2;n++){
if(lengthArray2[i]==lengthArray1[i]){
if(checkAnagram(*sentenceArray1[n],*sentenceArray2[i], length1)==1){ //Sends strings only to the checkAnagram function if they are of the same length.
printf("%d ",i);
}
}
}
printf("\n");
}
}
Supposed input and output:
I must have messed something up with the arrays and pointers somewhere, but the limited feedback from my console + my limited experience with C programming makes it hard to locate the error. My output gets as far to print "test4" once, and then crashes with the exception given in the title.
I hope what I want to achieve is clear, but I can't be any more precise on the error, unfortunately.
There is also a problem with:
for(i=0;i<=length1;i++){
You have one iteration past the array size:
int lengthArray1[length1];
If length1 is 5 then lengthArray1 has elements 0, 1, 2, 3, and 4, but your loop counts to 5. The condition should be i < length1, not i <= length1.
You should also use spaces around operators to make your code more readable.
The main error is at:
if(checkAnagram(*sentenceArray1[n],*sentenceArray2[i], length1)==1){
From the definition of checkAnagram it seems that it takes a character-array. But you are simply passing the value of the first char in both these arrays. So change it to:
if(checkAnagram(sentenceArray1[n],sentenceArray2[i], length1)==1){
This actually passes a pointer to the start of both the arrays. When I ran your code, and gave the input you specified it executed successfully, but the desired output wasn't coming.
Rest is up to your algorithm. Re-check it again.
This line:
if(checkAnagram(*sentenceArray1[n],*sentenceArray2[i], length1)==1){ //Sends strings only to the checkAnagram function if they are of the same length.
Errors out with "Type error in argument 1 to checkAnagram;found char expected pointer to char.
Errors out with "Type error in argument 2 to checkAnagram;found char expected pointer to char.
Remove the "*" from both argument 1 & 2.

Resources