How many anagrams there are in a sentence in C - c

I was asked to write a code that returns the maximum number of anagrams (word made by transposing the letters of another word like the word “secure” is an anagram of “rescue.”).
This is what I did:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char text[1000], angrm1[1000], angrm2[1000];
int i, j, k, count = 1, flag = 0, temp, size = 0, q = 1, counter = 0, max = 0;
char**point;
printf_s("Please enter the sentence, and then press Enter:\n");
gets(text);
strcpy_s(angrm1, 1000, text);
j = 1; i = 0;
for (i = 0; i < strlen(angrm1); i = k + 2) {
for (k = i; angrm1[k + 1] != ' '&&angrm1[k + 1]!=0; k++) {
if (angrm1[i] > angrm1[i + 1]) {
temp = angrm1[k];
angrm1[k] = angrm1[k + 1];
angrm1[k + 1] = temp;
}
}
Blockquote Arrange the words
size = strlen(angrm1);
}
for (i = 0; angrm1[i] != 0; i++)
{
if (angrm1[i] == ' ')
{
angrm1[i] = 0;
count++;
}
}
point = (char*)malloc(sizeof(char)*count);
for (i = 0; i < (size - 1); i++)
{
if (angrm1[i] == 0)
{
point[q] = &point[i + 1];
q++;
}
}
for (i = 0; i < counter; i++)
{
for (q = i + 1; q < counter; q++)
{
if (point[q] == 0 || point[i] == 0)
continue;
if (!strcmp(point[q], point[i]))
{
counter++;
point[q] = 0;
}
}
if (max < counter)
max = counter;
counter = 0;
}
printf_s("The maximum (not yet) number of anagram words in this sentence is %d", &max);
}
The first part works (in my opinion).
But when I check with the debugger, it skips the loop and I get junk.
Can someone please help me by pointing to the problem, and explaining how to fix it?

Related

Problem with counting elements in the list of names

I have made one program, where you enter a few characters (10 max). It makes you a list, count average length of surnames, tell about how much different names. But the problem is, when I enter the last number (10) - it sorts me it incorrectly (like 1, 10, 2, 3, 4, 5, 6, 7, 8, 9). Beneath I will present my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct people {
char num[2];
char surname[20];
char name[10];
} peoples[10], c;
int main()
{
int i, j, k = 0, l = 0, m = 0, n = 0;
float s = 0;
char str[100];
system("chcp 1251 > nul");
for (i = 0, j = 0; i < 10; i++, j++)
{
printf("Enter number, surname, name %d of your human: ", i + 1);
gets(str);
while (str[n] != '\n')
{
if (str[n] != ' ')
{
peoples[j].num[k] = str[n];
}
else
break;
n++;
k++;
}
n++;
k = 0;
while (str[n] != '\n')
{
if (str[n] != ' ')
{
peoples[j].surname[k] = str[n];
}
else
break;
n++;
k++;
}
n++;
k = 0;
while (str[n] != '\n')
{
if (str[n] != '\0')
{
peoples[j].name[k] = str[n];
}
else
break;
n++;
k++;
}
n = 0;
k = 0;
}
for (i = 0; i < 10; i++)
{
for (j = i + 1; j < 10; j++)
{
if (!strcmp(peoples[i].name, peoples[j].name))
m = 1;
}
if (m == 0)
l++;
m = 0;
s = s + strlen(peoples[i].surname);
}
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
if (strcmp(peoples[j].num, peoples[j+1].num) > 0)
{
c = peoples[j+1];
peoples[j+1] = peoples[j];
peoples[j] = c;
}
for (i = 0; i < 10; i++)
{
printf("%s ", peoples[i].num);
printf("%s ", peoples[i].name);
printf("%s ", peoples[i].surname);
printf("\n");
}
printf("\nYou have %d different names\n", l);
printf("Avarege lenght of surname is = %f\n", s / 10);
}
If you want to give numeric input, then use actual numeric data.
Change the num field to become an int instead of a single-character string:
struct people {
int num;
char surname[20];
char name[10];
};
Use fgets to read the line:
fgets(str, sizeof str, stdin);
[Error checking left as exercise for reader]
Then use e.g. sscanf for parse your string:
sscanf(str, "%d %s %s", &peoples[j].num, &peoples[j].name, &peoples[j].name);
[Error checking left as exercise for reader]
And finally, instead of doing your own sorting use the standard qsort function:
qsort(peoples, 10, sizeof(struct people), &compare_people_num);
With the comparison function being something like this:
int compare_people_num(const void *a, const void *b)
{
const struct people *p1 = a;
const struct people *p2 = b:
return p1->num - p2->num; // Change order to reverse sort
}
Using sscanf and qsort will make your code much simpler and easier to understand.

I wrote a code to print the union and intersection of two strings sets. I allocated memory in some parts.The last part is not working properly

The last part of the code where I am allocating memory to common_set is not working whereas other mallocs worked fine above. Similarly when I freed the unique_set for the third time it is not done properly. I am not able to get the printf sentences which I wrote after them. I am not able to free the pointer of the union_set. Also I am not able to allocate memory to a new pointer common_pointer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
void dict(char **str, int man, int MAY) {
char temp[MAY];
for (int i = 0; i < man; ++i) {
for (int j = i + 1; j < man; ++j) {
if (strcmp(str[i], str[j]) > 0) {
strcpy(temp, str[i]);
strcpy(str[i], str[j]);
strcpy(str[j], temp);
}
}
}
}
//int k = 0;
char **unique_set;
char **a_new_sumset;
int unique(char **s, int l, int d, int k) {
if (d == l) {
unique_set[k] = (char*)malloc((strlen(s[l]) + 1) * sizeof(char));
strcpy(unique_set[k], s[l]);
return k;
} else {
for (int i = l; i < d; i++) {
if (strcmp(s[i], s[i + 1]) == 0 && i + 1 == d) {
unique_set[k] = (char*)malloc((strlen(s[i + 1]) + 1) * sizeof(char));
strcpy(unique_set[k], s[i + 1]);
return k;
//printf("demo: %s\n", unique_set[k]);
} else
if (strcmp(s[i], s[i + 1]) != 0) {
unique_set[k] = (char*)malloc((strlen(s[i]) + 1) * sizeof(char));
strcpy(unique_set[k], s[i]);
//printf("demo1: %s\n", unique_set[k]);
k++;
unique(s, i + 1, d, k);
break;
}
}
}
}
char **common_set;
char **intersection(char **sum_set, int d) {
int k = 0;
for (int i = 0; i < d; i++) {
if (strcmp(sum_set[i], sum_set[i + 1]) == 0 && strcmp(sum_set[i], sum_set[i + 2]) != 0 && i + 2 < d) {
common_set[k] = (char*)malloc((strlen(sum_set[i]) + 1) * sizeof(char));
strcpy(common_set[k], sum_set[i]);
k++;
} else
if (strcmp(sum_set[i], sum_set[i + 1]) == 0 && i + 2 > d) {
common_set[k] = (char*)malloc((strlen(sum_set[i]) + 1) * sizeof(char));
strcpy(common_set[k], sum_set[i]);
k++;
}
}
return common_set;
}
#define maxx1 3 // number of words in grp 1
#define maxy1 10 // word limit for the first group of words
#define maxx2 3 // number of words in grp2
#define maxy2 10 // word limit for the next group of words
int main() {
char **sum_set;
char **str_g1;
char **str_g2;
char words1[maxy1];
str_g1 = (char**)malloc(maxx1 * sizeof(char*));
char words2[maxy2];
str_g2 = (char**)malloc(maxx2 * sizeof(char*));
printf("Enter the first group:\n");
for (int i = 0; i < maxx1; i++) {
gets(words1);
str_g1[i] = (char*)malloc((strlen(words1) + 1) * sizeof(char));
strcpy(str_g1[i], words1);
//puts(ptr[i]);
//printf("%d", i);
}
printf("Enter the second group:\n");
for (int i = 0; i < maxx2; i++) {
gets(words2);
str_g2[i] = (char*)malloc((strlen(words2) + 1) * sizeof(char));
strcpy(str_g2[i], words2);
//puts(ptr[i]);
//printf("%d", i);
}
dict(str_g1, maxx1, maxy1); //to lexicographically arrange the string 1 group
dict(str_g2, maxx2, maxy2);
sum_set = (char**)malloc((maxx1 + maxx2) * sizeof(char*));
a_new_sumset = (char**)malloc((maxx1 + maxx2) * sizeof(char*));
for (int i = 0; i < maxx1; i++) {
sum_set[i] = (char*)malloc((strlen(str_g1[i]) + 1) * sizeof(char));
strcpy(sum_set[i], str_g1[i]);
//puts(sum_set[i]);
}
for (int i = 0; i < maxx2; i++) {
sum_set[i + maxx1] = (char*)malloc((strlen(str_g2[i]) + 1) * sizeof(char));
strcpy(sum_set[i + maxx2], str_g2[i]);
//puts(sum_set[i + maxx1]);
}
dict(sum_set, maxx1 + maxx2, maxy1 + maxy2);
unique_set = (char**)malloc((maxx1) * sizeof(char*));//allocating memory to next string group to compute its set
int k = unique(str_g1, 0, maxx1 - 1, 0);
printf("%d \n", k);
printf("The set of the string A in arranged order is:\n");
for (int i = 0; i <= k; i++) {
a_new_sumset[i] = (char*)malloc((strlen(unique_set[i]) + 1) * sizeof(char));
strcpy(a_new_sumset[i], unique_set[i]);
puts(unique_set[i]);
//
}
//printf("freed the pointers\n");
for (int i = 0; i <= k; ++i) {//freeing the arrays
free(unique_set[i]);
}
free(unique_set);
//printf("freed the pointers\n");//freeing the top pointer
int a = k;
unique_set = (char**)malloc((maxx2) * sizeof(char*));//allocating memory to next string group to compute its set
k = unique(str_g2, 0, maxx2 - 1, 0);
int b = k;
printf("The set of the string B in arranged order is:\n");
for (int i = 0; i <= k; i++) {
a_new_sumset[i + 1 + a] = (char*)malloc((strlen(unique_set[i]) + 1) * sizeof(char));
strcpy(a_new_sumset[i + a + 1], unique_set[i]);
puts(unique_set[i]);
//strcpy(a_new_sumset[i + a + 1], unique_set[i]);
}
printf("%d \n", k);
for (int i = 0; i <= k; ++i) {//freeing the arrays
free(unique_set[i]);
}
free(unique_set);//freeing the top pointer
printf("freed the pointers\n");
unique_set = (char**)malloc((a + b) * sizeof(char*));//allocating memory to unique_set for computing the union of the sets
k = unique(sum_set, 0, (maxx1 + maxx2) - 1, 0);
printf("The set of the string A+B in arranged order is:\n");
for (int i = 0; i <= k; i++)
puts(unique_set[i]);
for (int i = 0; i <= k; ++i) {//freeing the arrays
free(unique_set[i]);
}
printf("freed the pointers\n");
free(unique_set);
printf("freed the pointers\n");
printf("The intersection_set of the string A+B in arranged order is:\n");
common_set = (char**)malloc((maxx1 + maxx2) * sizeof(char*));
printf("The intersection_set of the string A+B in arranged order is:\n");
char **p;
p = intersection(a_new_sumset, (maxx1 + maxx2) - 1);
printf("The intersection_set of the string A+B in arranged order is:\n");
for (int i = 0; i <maxx1 + maxx2; i++) {
puts(p[i]);
}
}
There are many issues in the code:
in function dict, you should not copy the strings, but swap the pointers instead, which is simpler and works for any string length. Furthermore the name dict is confusing for this function, prefer a more informative name such as sort_strings:
void sort_strings(char **str, int man) {
for (int i = 0; i < man; ++i) {
for (int j = i + 1; j < man; ++j) {
if (strcmp(str[i], str[j]) > 0) {
char *temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
}
}
global variables are not necessary for this task, prefer local variables, pass destination arrays as arguments and return the number of strings as the return value.
the string allocation code is duplicated everywhere... using the strdup() function or a wrapper that tests for memory allocation failure would improve readability.
avoid variable name l, which looks confusingly similar to 1
the uniq function does not return a value in the else branch, it is unclear what it does and why it is recursive.
the loop to add the strings from the second group has a bug: strcpy(sum_set[i + maxx2], str_g2[i]); should be strcpy(sum_set[i + maxx1], str_g2[i]);. This mistake has no effect now because maxx1 == maxx2 but should be fixed.
in function intersection, you compare strings at offset d + 1 and d + 2 before testing if these index values are within the array boundaries.
selecting duplicated strings in intersection makes the assumption that strings are not duplicated in group 1 and 2.
the number of common strings is not returned, nor stored into a global variable, so main() cannot determine this number and uses maxx1 + maxx2 which is always wrong for non trivial cases.
Here is a modified version using functions to read lines, sort an array, find unique values, compute the union and intersection of sets and free the string arrays:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// allocate a copy of a string or die
char *xstrdup(const char *str) {
char *p = strdup(str);
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
return p;
}
// read a line of at most max bytes
char *get_line(int max) {
char buf[max + 1];
int i = 0;
int c;
while ((c = getchar()) != EOF && c != '\n') {
if (i < max) {
buf[i++] = (char)c;
}
}
buf[i] = '\0';
return xstrdup(buf);
}
// free the strings in an array of size n
void free_strings(char **strings, int n) {
for (int i = 0; i < n; i++) {
free(strings[i]);
}
}
// copy strings in lexicographical order
int sort_strings(char **sorted, char **str, int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = i; j > 0 && strcmp(sorted[j - 1], str[i]) > 0; j--) {
sorted[j] = sorted[j - 1];
}
sorted[j] = xstrdup(str[i]);
}
return n;
}
// copy unique strings in lexicographical order
int uniq_strings(char **unique_strings, char **strings, int n) {
int i, k = 0;
for (i = 0; i < n; i++) {
if (i == 0 || strcmp(strings[i - 1], strings[i]) != 0) {
unique_strings[k++] = xstrdup(strings[i]);
}
}
return k;
}
int intersection_strings(char **intersection_set, char **str1, int n1, char **str2, int n2) {
int i = 0, j = 0, k = 0;
while (i < n1 && j < n2) {
int c = strcmp(str1[i], str2[j]);
if (c < 0) {
i++;
} else
if (c > 0) {
j++;
} else {
intersection_set[k++] = xstrdup(str1[i]);
i++;
j++;
}
}
return k;
}
int union_strings(char **union_set, char **str1, int n1, char **str2, int n2) {
int i = 0, j = 0, k = 0;
while (i < n1 && j < n2) {
int c = strcmp(str1[i], str2[j]);
if (c < 0) {
union_set[k++] = xstrdup(str1[i]);
i++;
} else
if (c > 0) {
union_set[k++] = xstrdup(str2[j]);
j++;
} else {
union_set[k++] = xstrdup(str1[i]);
i++;
j++;
}
}
while (i < n1) {
union_set[k++] = xstrdup(str1[i++]);
}
while (j < n2) {
union_set[k++] = xstrdup(str2[j++]);
}
return k;
}
void print_set(char **set, int n, const char *desc) {
if (desc) {
printf("%s", desc);
}
for (int i = 0; i < n; i++) {
puts(set[i]);
}
}
#define maxx1 3 // number of words in grp 1
#define maxy1 10 // word limit for the first group of words
#define maxx2 3 // number of words in grp2
#define maxy2 10 // word limit for the second group of words
int main() {
char *str_g1[maxx1];
char *str_s1[maxx1];
char *str_u1[maxx1];
char *str_g2[maxx2];
char *str_s2[maxx2];
char *str_u2[maxx2];
char *union_set[maxx1 + maxx2];
char *intersection_set[maxx1 < maxx2 ? maxx1 : maxx2];
printf("Enter the first group:\n");
for (int i = 0; i < maxx1; i++) {
str_g1[i] = get_line(maxy1);
}
printf("Enter the second group:\n");
for (int i = 0; i < maxx2; i++) {
str_g2[i] = get_line(maxy2);
}
sort_strings(str_s1, str_g1, maxx1);
int n1 = uniq_strings(str_u1, str_s1, maxx1);
sort_strings(str_s2, str_g2, maxx1);
int n2 = uniq_strings(str_u2, str_s2, maxx2);
print_set(str_u1, n1, "The set of the string A in arranged order is:\n");
print_set(str_u2, n2, "The set of the string B in arranged order is:\n");
// compute union and intersection
int nu = union_strings(union_set, str_u1, n1, str_u2, n2);
int ni = intersection_strings(intersection_set, str_u1, n1, str_u2, n2);
print_set(union_set, nu, "The set of the string A+B in arranged order is:\n");
print_set(intersection_set, ni, "The intersection_set of the string A*B in arranged order is:\n");
free_strings(str_g1, maxx1);
free_strings(str_g2, maxx2);
free_strings(str_s1, maxx1);
free_strings(str_s2, maxx2);
free_strings(str_u1, n1);
free_strings(str_u2, n2);
free_strings(union_set, nu);
free_strings(intersection_set, ni);
return 0;
}
To improve on this code, you can define a structure string_set to combine the string array along with variables describing its allocated size and active count. Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct string_set {
int count, size;
char **array;
} string_set;
// allocate a copy of a string or die
char *xstrdup(const char *str) {
char *p = strdup(str);
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
return p;
}
void *xalloc(size_t n) {
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
return p;
}
string_set *string_set_allocate(int size) {
string_set *set = xalloc(sizeof(*set));
set->count = 0;
set->size = size;
set->array = xalloc(sizeof(*set->array) * size);
return set;
}
void string_set_free(string_set *set) {
while (set->count --> 0) {
free(set->array[set->count]);
}
free(set->array);
free(set);
}
// read a line of at most max bytes
char *get_line(int max) {
char buf[max + 1];
int i = 0;
int c;
while ((c = getchar()) != EOF && c != '\n') {
if (i < max) {
buf[i++] = (char)c;
}
}
buf[i] = '\0';
return xstrdup(buf);
}
string_set *string_set_clone(string_set *set) {
string_set *copy = string_set_allocate(set->size);
for (int i = 0; i < set->count; i++) {
copy->array[i] = xstrdup(set->array[i]);
}
copy->count = set->count;
return copy;
}
void string_set_sort(string_set *set) {
for (int i = 0; i < set->count; i++) {
for (int j = i + 1; j < set->count; j++) {
if (strcmp(set->array[i], set->array[j]) > 0) {
char *temp = set->array[i];
set->array[i] = set->array[j];
set->array[j] = temp;
}
}
}
}
void string_set_uniq(string_set *set) {
if (set->count > 0) {
int j = 1;
for (int i = 1; i < set->count; i++) {
if (strcmp(set->array[i], set->array[j - 1]) == 0) {
free(set->array[i]);
set->array[i] = NULL;
} else {
set->array[j++] = set->array[i];
}
}
set->count = j;
}
}
string_set *string_set_intersection(string_set *set1, string_set *set2) {
int n1 = set1->count;
int n2 = set2->count;
string_set *res = string_set_allocate(n1 < n2 ? n1 : n2);
int i = 0, j = 0, k = 0;
while (i < n1 && j < n2) {
int c = strcmp(set1->array[i], set2->array[j]);
if (c < 0) {
i++;
} else
if (c > 0) {
j++;
} else {
res->array[k++] = xstrdup(set1->array[i]);
i++;
j++;
}
}
res->count = k;
return res;
}
string_set *string_set_union(string_set *set1, string_set *set2) {
int n1 = set1->count;
int n2 = set2->count;
string_set *res = string_set_allocate(n1 + n2);
int i = 0, j = 0, k = 0;
while (i < n1 && j < n2) {
int c = strcmp(set1->array[i], set2->array[j]);
if (c < 0) {
res->array[k++] = xstrdup(set1->array[i]);
i++;
} else
if (c > 0) {
res->array[k++] = xstrdup(set2->array[j]);
j++;
} else {
res->array[k++] = xstrdup(set1->array[i]);
i++;
j++;
}
}
while (i < n1) {
res->array[k++] = xstrdup(set1->array[i++]);
}
while (j < n2) {
res->array[k++] = xstrdup(set2->array[j++]);
}
res->count = k;
return res;
}
void string_set_print(string_set *set, const char *desc) {
if (desc) {
printf("%s", desc);
}
for (int i = 0; i < set->count; i++) {
puts(set->array[i]);
}
}
#define maxx1 3 // number of words in grp 1
#define maxy1 10 // word limit for the first group of words
#define maxx2 3 // number of words in grp2
#define maxy2 10 // word limit for the second group of words
int main() {
string_set *str_g1 = string_set_allocate(maxx1);
string_set *str_g2 = string_set_allocate(maxx2);
printf("Enter the first group:\n");
for (int i = 0; i < maxx1; i++) {
str_g1->array[str_g1->count++] = get_line(maxy1);
}
printf("Enter the second group:\n");
for (int i = 0; i < maxx2; i++) {
str_g2->array[str_g2->count++] = get_line(maxy2);
}
string_set *str_u1 = string_set_clone(str_g1);
string_set_sort(str_u1);
string_set_uniq(str_u1);
string_set *str_u2 = string_set_clone(str_g2);
string_set_sort(str_u2);
string_set_uniq(str_u2);
string_set_print(str_u1, "The set of the string A in arranged order is:\n");
string_set_print(str_u2, "The set of the string B in arranged order is:\n");
string_set *union_set = string_set_union(str_u1, str_u2);
string_set *intersection_set = string_set_intersection(str_u1, str_u2);
string_set_print(union_set, "The set of the string A+B in arranged order is:\n");
string_set_print(intersection_set, "The intersection set of the string A*B in arranged order is:\n");
string_set_free(str_g1);
string_set_free(str_g2);
string_set_free(str_u1);
string_set_free(str_u2);
string_set_free(union_set);
string_set_free(intersection_set);
return 0;
}
The last part of the code where I am allocating memory to common_set is not working ...
The problem in this part is not the allocation, but the implementation of the intersection function. You haven't provided a means for this function to return the number of elements in the intersection set, and you haven't initialized the allocated set space - you just try to access maxx1 + maxx2 set elements, most of which are undefined. Fixing this design would be a start.

How to find the two most common letters in a string?

The purpose of my code is to tell the user what is the most common letter and the second most common letter in the string and replace them with each other, but my code doesn't work properly. It finds the most common letters but doesn't replace them or print them properly. What is the problem?
Example input:
i love this game i do do
Output (this line is printed):
Most common: i, 2nd most common: o
After that I expected this output, which is not printed:
o live thos game o di o di
Code:
int main()
{
char array[MAX_LEN] = {0};
int i = 0, j = 0;
int max = 0, secondMAX = 0, count = 0, save = 0;
char saveForNow = ' ', highest = ' ', secondHighest = ' ';
printf("Enter a string:\n");
fgets(array, MAX_LEN, stdin);
array[strcspn(array, "\n")] = 0;
for(i = 0; i < strlen(array); ++i)
{
for(j = 0; j < strlen(array); j++)
{
if(array[i] != ' ')
{
if(array[i] == array[j])
{
count++;
saveForNow = array[i];
}
}
}
if(count > max)
{
max = count;
highest = saveForNow;
}
else if((count < max) && (count > secondMAX))
{
secondMAX = count;
secondHighest = saveForNow;
}
count = 0;
}
//*I think the proplem is here
for(i = 0; i < strlen(array); i++)
{
if(array[i] == highest)
{
array[i] = secondHighest;
}
else if(array[i] == secondHighest);
{
array[i] = highest;
}
}
printf("Most common: %c, ", highest);
printf("2nd most common: %c\n", secondHighest);
printf("Swapped:\n");
printf("%s", array);
//*I think the proplem is here
}

Counting the occurances of a word in a sentence in C

As mentioned in the heading, I am having problems while extracting a word from a sentence. It is giving a "break-point error". Can anyone help me understand how am I messing up, as I am just a beginner.
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int main()
{
char* word_array[50], input[51], word[51], temp[51];
short i , j, k, flag;
i = j = k = flag = 0;
printf("Enter the sentence (max 50 characters):\n");
gets_s(input, 50);
printf("\nEnter the word to be searched : ");
gets_s(word, 50);
while (input[i] != NULL)
{
while (input[i] == ' ')// skip the spaces
i = i + 1;
k = 0;
while (input[i] != ' ' || input[i] != NULL)//extract the words
{
word_array[j] = (char*)malloc(50 * sizeof(char));
*(*(word_array + j) + k) = input[i];
k = k + 1;
i = i + 1;
}
*(*(word_array + j) + k) = '\0';
printf("\nProcessed word : %s", word_array[j]);//just for debugging
j = j + 1;
}
for (i = 0; i <= j; i++)
if (strcmp(word_array[i], word) == 0)
flag = flag + 1;
printf("\nThe word occurred in the sentence %hu times.\n\n", flag);
system("pause");
return 0;
}

Freeing up memory with free function causing my program to crash

I could use some help with my program,
I wrote a program that is counting the number of anagrams in a sentence, for which I am using a malloc() function, you can see in my code **ArrPtr=malloc.
I use this to count the anagrams, after finishing it I want to continue to my second part of the program and I wish to free the memory with free(arrPtr);
and the program crashes (It didn't crash when I did not use the free option).
Here's my code,
void main()
{
char str[1001] = { 0 };
char temp[1001] = { 0 }, temp2;
char strB[1001] = { 0 };
int printf_i, counter, i, q, flag, j = 1, r = 0, m = 1, length = 0, root = 0, m1 = 0;
int max_analogy = 0, counter2 = 0, O, sum, sum2;
char **arrPtr;
int k = 0;
int **matrix;
printf("Please enter the sentence, and then press Enter:\n");
gets(str);
//bubble sort
strcpy_s(strB, 1001, str);
for (i = 0; i < strlen(strB); i = q + 2)
{
do
{
flag = 0;
for (q = i; strB[q + 1] != 32 && strB[q + 1] != 0; q++)
{
if (strB[q] > strB[q + 1])
{
// Swap
temp2 = strB[q];
strB[q] = strB[q + 1];
strB[q + 1] = temp2;
flag = 1;
}
}
} while (flag != 0);
}
counter = 1;
length = strlen(strB);
for (i = 0; strB[i] != 0; i++)
{
if (strB[i] == 32)
{
strB[i] = 0;
counter++;
}
}
arrPtr = (char*)malloc(sizeof(char)*counter);
arrPtr[0] = strB;
q = 1;
for (i = 0; i < length - 1; i++)
{
if (strB[i] == 0)
{
arrPtr[q] = &strB[i + 1];
q++;
}
}
counter2 = 0;
for (i = 0; i < counter; i++)
{
for (q = i + 1; q < counter; q++)
{
if (arrPtr[q] == 0 || arrPtr[i] == 0)
continue;
if (!strcmp(arrPtr[q], arrPtr[i]))
{
counter2++;
arrPtr[q] = 0;
}
}
if (max_analogy < counter2)
max_analogy = counter2;
counter2 = 0;
}
printf("The maximum number of anagram words in this sentence is %d.\n", max_analogy);
free(arrPtr);
}
arrPtr = (char*)malloc(sizeof(char)*counter);
is wrong fo many reason:
arrPtr is (char **).
cast using a C compiler is useless and dangerous.
you must allocate sizeof(char *)
reason 3 is the real reason of you problem: you are allocating counter bytes while you write counter*sizeof(char *) (most probably counter*8), so you are writing out of bounds of allocated memory corrupting malloc memory pool.
You can fix it using
arrPtr = malloc(sizeof(char *)*counter);

Resources