xavier666 56 Junior Poster

I'm sorry for all the trouble Banfa, i found about the error. The problem was a different matter entirely.

See Line # 144 int * array_temp = (int *)malloc(sizeof(array)); I was using sizeof(array) . I was expecting it to give me the size of entire memory allocated to array but it is actually giving me size of int So i changed my code to int * array_temp = (int *)calloc(size_of_array,sizeof(int)); Where size_of_array is the size of the given array and now it's all working fine
_________________________________________________________

Here's another problem. When I compile this line in my COLLEGE COMPILER, it gives a warning but no error int * array = malloc(sizeof(int)); But my HOME COMPILER flags it as an error. But ideally, neither of them shouldn't say anything. Why this anomaly?

xavier666 56 Junior Poster

Okay. I'm really becomming mad now. Here is the code from my college compiler and it's respective output

# include <stdio.h>
# include <stdlib.h>

void array_input    ( int *, int                );
void array_display  ( int *, int                );
void array_merge    ( int *, int , int , int    );
void sort_merge     ( int *, int , int          );
void pause          ( void                      );

int main()
{
    int option;
    int size_of_array = 0;
    int *array = NULL;

    do
    {
        printf("\n\t=========================================");
        printf("\n\t|          SORTING TECHNIQUES           |");
        printf("\n\t=========================================");
        printf("\n\n\tEstablish The Size Of Array           [1]");
        printf("\n\n\tEnter The Elements Into The Array     [2]");
        printf("\n\n\tUse Sorting Method : Merge Sort       [5]");
        printf("\n\n\tDisplay The Array                     [8]");
        printf("\n\n\tExit                                  [0]");

        printf("\n\n\t\tEnter Choice : ");
        scanf("%d", &option);

        switch (option)
        {
            case 1 :
                if(array != NULL)
                    free(array);

                printf("\n\n\t\tEnter The Size Of Array : ");

                scanf("%d", &size_of_array);

		if(size_of_array < 1)
		{    
		    printf("\n\n\t\tInvalid Size!");
		    size_of_array = 0;
 		}

                pause();
                break;

            case 2 :
                if (size_of_array < 1)
                {
                    printf("\n\n\t\tInvalid Size Of Array!");
                }
                else
                {
                    if(array != NULL)
		    	free(array);

		    array = (int *)calloc(size_of_array,sizeof(int));

		    if(array == NULL)
		    {
			printf("\n\n\t\tUnable To Allocate Memory!");
			return EXIT_FAILURE;
		    }

                    printf("\n\n\t\tEnter The Elements Into The Array : ");
                    array_input(array,size_of_array);
                }
                pause();
                break;

            case 5 :
                if (array == NULL)
                {    
		    printf("\n\n\t\tEmpty Array!");
                }
                else
                {
                    sort_merge(array,0,size_of_array);
                    printf("\n\n\t\tYour Array Has Been Sorted ... ");
                }
                pause();
                break;

            case 8 :
                if (array == NULL)
                {
                    printf("\n\n\t\tEmpty Array!");
                }
                else
                {
                    printf("\n\n\t\tYour Array : ");
                    array_display(array,size_of_array);
                }

                pause();
                break;

            case 0 :
                printf("\n\n\t\tThank You!");
                break;

            default:
                printf("\n\n\t\tWrong Option!\n\n\t\tTry Again");
                pause(); …
xavier666 56 Junior Poster

I am using Code::Blocks 8.02 editor
When I go to Settings -> Compiler & Debugger, i see that "Selected Compiler" is 'GNU GCC Compiler'
The name of my file is sort_merge.c
I gave it a [DOT]C extension. I still can't figure out what I'm doing wrong.

What compiler do you people use?

xavier666 56 Junior Poster

Line 49 of the new listing, only free array if array is not NULL or you willl get a run time error.

I don't get this error. I mean if i try to free a NULL memory, it does not say anything.

and you have failed to include stdlib.h

Hey! Look at line# 2 :P

Casting the return value causes problems if your code needs to be portable or work on 64bit systems

This was another one of my doubts. If i don't type caste calloc/malloc, my compiler is giving me errors. Take a look

# include <stdio.h>
# include <stdlib.h>

int main()
{
    int * element = malloc(sizeof(int));
    int * array   = calloc(5,sizeof(int));

    free(element);
    free(array);

    return EXIT_SUCCESS;
}

These are the error messages

In function `int main()':|
LINE |6| error: invalid conversion from `void*' to `int*'|
LINE |7| error: invalid conversion from `void*' to `int*'|
||=== Build finished: 2 errors, 0 warnings ===|
xavier666 56 Junior Poster

I can't explain why it is working at home, but that is the nature of undefined behaviour

I hate this s**t

Okay after reading everything above this post. Here's what i think i have done wrong

1) Took the size of array from user BUT DID NOT check for negative inputs
2) Freed the memory AND AFTER THAT tried to store numbers at that memory location

@Banfa & @Adak
Bit confused here. Which standard should i follow? int *array = (int *)calloc(sizeof(int)); OR int *array = (int *)calloc(sizeof(int *)); This may sound lame but all the books that i've seen have used the first type of allocation method

@mitrmkar
I'll get back to you later. Have to go to sleep

Here is the corrected code but i don't know whether it's error free. Have to try it out at college

# include <stdio.h>
# include <stdlib.h>

void array_input    ( int *, int                );
void array_display  ( int *, int                );
void array_merge    ( int *, int , int , int    );
void sort_merge     ( int *, int , int          );
void pause          ( void                      );

int main()
{
    int option;
    int size_of_array = 0;
    int *array = NULL;

    do
    {
        printf("\n\t=========================================");
        printf("\n\t|          SORTING TECHNIQUES           |");
        printf("\n\t=========================================");
        printf("\n\n\tEstablish The Size Of Array           [1]");
        printf("\n\n\tEnter The Elements Into The Array     [2]");
        printf("\n\n\tUse Sorting Method : Merge Sort       [5]");
        printf("\n\n\tDisplay The Array                     [8]");
        printf("\n\n\tExit                                  [0]");

        printf("\n\n\t\tEnter Choice : ");
        scanf("%d", &option);

        switch (option)
        { …
xavier666 56 Junior Poster

Okay, this time, i have to say it's a weird error. This code runs fine in Code::Blocks 8.02 but fails to run in my college compiler.
I think my college compiler is the GCC Compiler (same as my home compiler) but in LINUX environment.
Something like

vi sort.c
cc sort.c -o sort
./sort

Here is the code ...

# include <stdio.h>
# include <stdlib.h>

void array_input    ( int *, int                );
void array_display  ( int *, int                );
void array_merge    ( int *, int , int , int    );
void sort_merge     ( int *, int , int          );
void pause          ( void                      );

int main()
{
    int option;
    int size_of_array = 0;
    int *array = NULL;

    do
    {
        printf("\n\t=========================================");
        printf("\n\t|          SORTING TECHNIQUES           |");
        printf("\n\t=========================================");
        printf("\n\n\tEstablish The Size Of Array           [1]");
        printf("\n\n\tEnter The Elements Into The Array     [2]");
        printf("\n\n\tUse Sorting Method : Merge Sort       [5]");
        printf("\n\n\tDisplay The Array                     [8]");
        printf("\n\n\tExit                                  [0]");

        printf("\n\n\t\tEnter Choice : ");
        scanf("%d", &option);

        switch (option)
        {
            case 1 :
                if(array != NULL)
                    free(array);
                printf("\n\n\t\tEnter The Size Of Array : ");
                scanf("%d", &size_of_array);
                array = (int *)calloc(size_of_array,sizeof(int));
                pause();
                break;

            case 2 :
                if (size_of_array < 1)
                {
                    printf("\n\n\t\tInvalid Size Of Array!");
                }
                else
                {
                    free(array);
                    printf("\n\n\t\tEnter The Elements Into The Array : ");
                    array_input(array,size_of_array);
                }
                pause();
                break;

            case 5 :
                if (array == NULL)
                {
                    printf("\n\n\t\tEmpty Array!");
                }
                else
                {
                    sort_merge(array,0,size_of_array);
                    printf("\n\n\t\tYour Array Has Been Sorted ... ");
                }
                pause();
                break;

            case 8 :
                if (array == NULL)
                {
                    printf("\n\n\t\tEmpty Array!");
                }
                else
                { …
xavier666 56 Junior Poster

LINE 13 - while(c < 5)
When c = 4, array index is out of its bounds. The problem with C is that it C will not check for such array out of bounds conditions. The program will compile and run but will give the error at the end of its execution
LINE 10 - for(b=0;b<12;b++)
Any particular reason for giving 12? Again another array out of bounds...
Here is your corrected program...

#include<stdio.h>

int main()
{
	int yo[4][4];
	int b;
	int c;

	for(b = 0; b < 4; b++)
	{
		c = 0;
		while(c < 4)
		{
			yo[b][c] = b*c;
			printf("a[%d][%d]  =   %d\n",b,c,(yo[b][c]));
			c++;
		}
	}

	getchar();
	return 0;

}
xavier666 56 Junior Poster
#include <conio.h>
#include <iostream>
 
int main(int argc, char *argv[])
{
    char k;
 
    k = getch();
 
    if (k==27)
       printf("ESC pressed.\n");
 
    return EXIT_SUCCESS;
}

Agreed but what are you going to do about this thing -> conio.h Mind you, your code is not portable at this point. (Unless you make an exe out of it)

conio.h is a C header file used ONLY in old MS-DOS compilers to create text user interfaces. It is NOT part of the C standard library, ISO C nor is it required by POSIX.

Source - Wikipedia
So you might wanna look at what the other people have said above
:)

xavier666 56 Junior Poster

The secondary array is set in main(), statically. No malloc/calloc is used.

Have you made the sorting code inside a function? If yes, then are you sending the temporary array as parameter to the function?

If you add the insertion sort optimization to Quicksort, you will have a much faster sorter, which uses less space than merge sort, of any kind.

Optimization of sorting algorithms is a totally new ball game, much complex than the sorting algorithm itself. I just started sorting (1st Year in college) so I can't really discuss anything about it, however ;), I've found out that optimization again depends on the type and size of data the sorting algorithm is dealing with
I've heard that some sorting techniques are good for large amount of data. Some are good for partially sorted lists and so on...

http://www.eternallyconfuzzled.com/jsw_home.aspx
http://www.planet-source-code.com/
http://www.algorithmist.com/index.php/Main_Page
http://www.cosc.canterbury.ac.nz/mukundan/JavaP.html

You can try the above links, for your "library sort". Let me know if you find something
Cheers!

xavier666 56 Junior Poster

Radix sort will require an auxiliary array, as well.

I have not used radix sort in my program

What I've done for my AllSorts program, is have the second array made equal to the size of the original array.

But what is the size of the original array? Have you taken the size from user or used # define . Using a macro is cheap but if the size of the temporary array is to be of the same size as the original array, one has to use malloc, calloc etc (as far as I know)

Your program may run fast but will not run for any size of array, mine on the other hand, will run for any size of array. Sure it may run slow but that's it.

You should not be repeatedly allocating memory - that is a substantial slow down to a sorting program.

What we have finally come across is a trade-off between space and time. Well, i chose space over time.

I found out that there is no such thing as a general quick, merge, heap ... sort. Even they are modified to suit the type and size of data they will handle.

You can try "Google Uncle" for "Library Sort"

xavier666 56 Junior Poster

Can't your teacher(if any) solve the problems that you are facing in pointers?
If you have none, experiment with pointers. You'll learn a lot.
You can post your doubts here but don't expect instant answers.

xavier666 56 Junior Poster

You cannot write

username == 'udental'

It's not that he cannot write it. Technically speaking, it's not a syntax error but it will always be evaluated to false.
(At least my Code::Blocks compiler tells me that)

As per my knowledge, we are trying to check the equality of two char pointers of two different strings (which is always different). Hence always false

@HBK_100 #include <conio.h> Argh! The infernal and vile conio.h, please trash it! There are many alternatives to getch() And also try to avoid system calls. They are
1) Slow
2) Risky to use
3) Reduces portability of your code

xavier666 56 Junior Poster

Only for merge sort. The rest of the algorithms do not need a temporary array.
By the way, Happy Holi!

xavier666 56 Junior Poster

You could've posted a list of books you didn't find useful.

You can try this

You should take it slow while studying this book

xavier666 56 Junior Poster

Actually, i wrote the print command as a function.

void array_display  (int *array, int size_of_array)
{
    int i;
    for (i = 0; i < size_of_array; i++)
    {
        printf("\n\t\t\t%d.\t%d", (i + 1), array[i]);
    }
}

The whole program is in switch case so it actually does not matter where i wrote it

Here is the menu of my program

=========================================
|          SORTING TECHNIQUES           |
=========================================

Establish The Size Of Array           [1]

Enter The Elements Into The Array     [2]

Use Sorting Method : Insertion Sort   [3]

Use Sorting Method : Quick Sort       [4]

Use Sorting Method : Merge Sort       [5]

Use Sorting Method : Shell Sort       [6]

Display The Array                     [7]

Exit                                  [0]

        Enter Choice :

And I've written the respective commands as functions.

Here is another bizarre output of my program

SIZE OF ARRAY - 5

INPUTS - 5,4,3,2,1

LENGTH OF ARRAY - 2     LOW - 0 HIGH - 1

LENGTH OF ARRAY - 3     LOW - 0 HIGH - 2

LENGTH OF ARRAY - 5     LOW - 3 HIGH - 4

LENGTH OF ARRAY - 6     LOW - 3 HIGH - 5

LENGTH OF ARRAY - 6     LOW - 0 HIGH - 5

AFTER SORTING - 3,0,0,0,0

Thanks for your effort though!

xavier666 56 Junior Poster

Use Code::Blocks
No problems and no hassles!

xavier666 56 Junior Poster

I just received the MERGE SORT code from my friend, here it is

void sort_merge     (int *array, int low, int high)
{
    int mid;

    if (low < high)
    {
        mid = (low + high) / 2;
        sort_merge  (array, low, mid);
        sort_merge  (array, mid + 1, high);
        array_merge (array, low, high, mid);
    }
}

void array_merge    (int *array, int low, int high, int mid)
{
    int i = low;
    int j = mid + 1;
    int k = low;
    int array_temp[50];

    while (i <= mid && j <= high)
    {
        if (array[i] < array[j])
        {
            array_temp[k++] = array[i++];
        }
        else
        {
            array_temp[k++] = array[j++];
        }
    }

    while (i <= mid)
    {
        array_temp[k++] = array[i++];
    }

    while (j <= high)
    {
        array_temp[k++] = array[j++];
    }

    for (i = low; i < k; i++)
    {
        array[i] = array_temp[i];
    }
}

It's running okay, however, it has a problem. You'll see that in array_merge, it has declared array_temp[50] and
hence, it is static. If size of array is small, this program becomes inefficient and if
size of array is large, this won't work. So i made a modification, that is,
printed the values of low, high & k

void array_merge    (int *array, int low, int high, int mid)
{
    int i = low;
    int j = mid + 1;
    int k = low;
    int array_temp[50];

    while (i <= mid && j <= high)
    {
        if (array[i] < array[j])
        {
            array_temp[k++] = array[i++];
        }
        else
        {
            array_temp[k++] = array[j++];
        } …
xavier666 56 Junior Poster

int * my_array = (int *)calloc(SIZE,sizeof(int)); [ ][ ][ ][ ][ ] // SOME INPUT OF NUMBERS [1][2][3][4][5] free(my_array); But each of the array elements individually have an address
So when we free(my_array) , all of them dissapear together [poof!][poof!][poof!][poof!][poof!] Is this what happens?

Or this [poof!] <- first address Then what happens to the rest of the elements?

xavier666 56 Junior Poster

Let's say we want to free the total memory used by a linked list in a program, I generally do it like this

typedef struct linked_list
{
    int some_data;
    struct linked_list *link;
}NODE;

int free_memory(NODE * head)
{
    NODE * temp = NULL;
    
    if(head == NULL)
        return 0;       //  FAILURE IN FREEING MEMORY
    else
    {
        while(head != NULL)
        {
            temp = head;
            head = head -> link;
            free(temp);
        }
    }
    
    return 1;           //  SUCCESS IN FREEING MEMORY
}

Now suppose I've created an array

int * create_array(int size_of_array)
{
    int * array = (int *)calloc(size_of_array,sizeof(int));
    
    return array;
}

Rarely have I seen books freeing memory but sometimes I've seen this

# define SIZE 5

int * create_array( int );

int main()
{
    int * my_array = create_array(SIZE);
    
    //  SOME OPERATION HAS BEEN DONE ON THE ARRAY
    //  NOW FREEING MEMORY
    
    free(my_array);
    
    return 0;
}

But I free memory like this

# define SIZE 5

int * create_array( int );

int main()
{
    int * my_array = create_array(SIZE);
    
    //  SOME OPERATION HAS BEEN DONE ON THE ARRAY
    //  NOW FREEING MEMORY
    
    free_memory(my_array, SIZE);
    
    return 0;
}
    
int free_memory (int * array, int size_of_array)
{
    if(array == NULL)
        return 0;
    else
    {
        int i;
        for(i = size_of_array - 1; i >= 0; i--)
        {
            free(array[i]);
        }
    }
    
    return 1;
}

So in a nut-shell, when we are freeing a linked list, we are freeing each node separately, but when we are freeing an array, the books are freeing …

xavier666 56 Junior Poster

Or you could just take my word for it and not worry about ever encountering it (except in other people's code).

Listen, i don't doubt you but I basically live my life around these quotes

Why do we fall master Wayne, so that we can learn to pick ourself up again

Don't make the same mistakes as i did, make your own mistakes

I believe everyone should experiment with mistakes for a better understanding of a subject.
After much philosophy, can you give me a snippet, where that printf error occurs? I'll test it in my college.

xavier666 56 Junior Poster

It's still initialized, but now the scope of the variable is limited to the else clause (the only place you actually use it). Readers won't wonder where else you use i because it's declared at the top of main.

So in a nut-shell, reduce the scope of all variables as much as possible so that the reader will know at once where and why it is used

>I still have to come across this error
Let me guess: you use Windows.

Right on target.
But in my college, we use Unix/Linux but still didn't encounter it. Guess i'll have to learn it the hard way

xavier666 56 Junior Poster

>while(i < length)
You only use for this loop, yet it's declared at the top of main. Wouldn't it be easier to read the code if your variables are declared closer to where they're used? Further, your while loop is constructed identically to a for loop, so I'd say a for loop makes more sense here.

You can thank Borland for that. There, we first have to initialize all variables before using them. Guess old habits die hard

>return 0;
>break;
The break is redundant; it'll never be reached because you return on the previous line.

C**p! I was deleting all of the break s and forgot that one

>if(input < 48 || input > 56)
>converted_number = converted_number*10 + (input - 48);

If i say to my teacher "then we subtract '0' from the character, then we get the numeric equivalent", she will say "x - 0 = x"
Point noted. All of us here have been brought up learning ASCII

>printf("Enter Input : ");
The stream isn't guaranteed to be flushed unless you print a newline or call fflush. The user may not see your prompt before fgets starts blocking, which is generally very confusing.

I still have to come across this error


Thanks again!

xavier666 56 Junior Poster

You could also do something like this

....
    char input[10];
    int converted_number = 0;
    int length;
    int i = 0;
    
    printf("Enter Input : ");
    fgets(input,10,stdin);
    input[strlen(input) - 1] = '\0';

    if(strlen(input) > 2)    // number is within 20 hence must be within 2 digits
    {
        printf("Invalid");
        return 0;
    }
    else
    {
        length = strlen(input);

        while(i < length)
        {
            if(input[i] < 48 || input[i] > 56)    //  if one of the characters is not a number, then immediate exit
            {
                printf("Invalid");    
                return 0;
                break;
            }
            else
            {
                converted_number = converted_number*10 + (input[i] - 48);    // converting the number to integer
            }
            
            i++;
        }
    }

    if(converted_number < 0 || converted_number > 20)
        printf("Invalid");
    else
        printf("Valid");
    ....
xavier666 56 Junior Poster

>usercheck[strlen(usercheck) - 1] = '\0';
While this covers the average case, it's possible for fgets to succeed yet not end with a newline. Unless you want an edge case bug where a legitimate character is deleted, you should check for the presence of a newline first:

I had completely forgotten about that
Thanks

>fgets(usercheck,256,stdin);
Don't forget to check for failure. The last thing you want to do is dereference a null pointer on the next line.

Can you give me an example as to where this error occurs?

xavier666 56 Junior Poster

@latszer
Hello,
LINE 17 - You cannot assign a array to another array
I think you were trying to use the == sign but it is not allowed for strings, i'e, username_1==usercheck . It will not give any error but it will always be evaluated to false.
Use strcmp as Dave has pointed out
Also, don't use gets . Use his/her cousin fgets . I've demonstrated in the program below. Also read the link by WaltP

# include <stdio.h>
# include <string.h>

# define username_1 "greg"
# define password_1 "going"

int main(void)
{
    char usercheck[256];
    char password[256];

    printf("What is your username? ");
    fgets(usercheck,256,stdin);
    usercheck[strlen(usercheck) - 1] = '\0';    //  REMOVING NEWLINE FROM 
                                                //  THE END OF THE STRING
                                                
    if ( strcmp(username_1,usercheck) == 0 )
    {
        printf("What is your password? ");
        fgets(password,256,stdin);
        password[strlen(password) - 1] = '\0';  //  REMOVING NEWLINE FROM 
                                                //  THE END OF THE STRING

        if ( strcmp(password,password_1) == 0 )
        {
            printf("You May Enter!\n");
        }
    }
    else
    {
        printf("access denied.\n");
    }

    return 0;
}

@csmgsarma
Please clear your concepts of C
It's good that you're trying to help but please don't spread wrong knowledge

xavier666 56 Junior Poster

If you just have a text editor you can probably write a program to pare down your code to the strings (marked by a line number), import that into word, correct everything and make your changes by hand.

But the problem with that method is that it will even flag scanf, printf, struct etc as errors.
@ithelp
If you can painstakingly add the syntaxial words in to the in-built dictionary, i think you would be better off.
But mind you, turn of the grammatical error flagging system. Then there would be no end to pain

xavier666 56 Junior Poster

Yes this will get ride of the memory leak...but it will also get get of the pointer you passed to the function.
The point I'm trying to make is, is this the functionality you want in this function? Dynamic memory runtime errors are very hard to track down so I would take a minute and think about it...

The functionality that I would like is as follows

There is a Double-Link List or Two-Way List.
There is also a function

void add_node_at_front ( int element_to_be added , struct **list head_of_list );

Now if a new element is to be added, head address will also be modified. I could have done it by returning the address. But my special requirement is not to return but instead pass the reference of the head address which will be modified. And hence, this thread.

Now i didn't understand this part

but it will also get get of the pointer you passed to the function

??

xavier666 56 Junior Poster

Okay, done! Thanks gerard4143!
Now i can go back to my double-link list and DEQUE program.

There is also another clarification. How do I fix the memory leak? I've made an attempt inside the program. Please check whether it's correct or not...

# include <stdio.h>
# include <stdlib.h>

//  COMPILER    :   GNU GCC COMPILER
//  EDITOR      :   CODE::BLOCKS 8.02

struct test
{
    int data;
    struct test *link;
};

void change(struct test **);

int main()
{
    struct test *fresh = (struct test *)malloc(sizeof(struct test));
    struct test *temp = NULL;

    int some_data = 10;

    fresh -> data = some_data;
    fresh -> link = NULL;

    printf("\n\n\tBefore Going Into Function");

    printf("\n\n\tData = %d\t\tAddress %x", fresh -> data, fresh);
    printf("\n\n\t____________________________________________________________");

    change(&fresh);

    printf("\n\n\tAfter Getting Out Of Function");

    printf("\n\n\tData = %d\t\tAddress %x", fresh -> data, fresh);
    printf("\n\n\t____________________________________________________________");

    return 0;
}

void change(struct test **some_ptr)
{
    struct test *new_fresh = (struct test *)malloc(sizeof(struct test));

    free(*some_ptr);        //  SHOULD I BE DOING SOMETHING LIKE THIS?
                            //  OR IS THIS REDUNDANT?
                            //  PESONAL OPINION - IT SHOULD BE DONE

    *some_ptr = new_fresh;

    new_fresh -> link = NULL;

    new_fresh -> data = 20;

    printf("\n\n\tInside Function");
    printf("\n\n\tData = %d\t\tAddress %x", new_fresh -> data, new_fresh);
    printf("\n\n\t____________________________________________________________");
}
xavier666 56 Junior Poster

Note your code generates a memory leak on line 43

BTW, is leaking memory like you are doing also a requirement?

Since it was a small program, i thought it wouldn't hurt to have a small leak. Don't worry, I always free memory in big programs and hence forth, I'll also do even in small programs.

xavier666 56 Junior Poster

@Salem
Do you write that link from memory or by copy-pasting?

xavier666 56 Junior Poster

Here is the sample program

# include <stdio.h>
# include <stdlib.h>

//  COMPILER    :   GNU GCC COMPILER
//  EDITOR      :   CODE::BLOCKS 8.02

struct test
{
    int data;
    struct test *link;
};

void change(struct test *ptr);

int main()
{
    struct test *fresh = (struct test *)malloc(sizeof(struct test));

    int some_data = 10;

    fresh -> data = some_data;
    fresh -> link = NULL;

    printf("\n\n\tBefore Going Into Function");

    printf("\n\n\tData = %d\t\tAddress %x", fresh -> data, fresh);
    printf("\n\n\t____________________________________________________________");

    change(fresh);

    printf("\n\n\tAfter Getting Out Of Function");

    printf("\n\n\tData = %d\t\tAddress %x", fresh -> data, fresh);
    printf("\n\n\t____________________________________________________________");

    return 0;
}

void change(struct test *some_ptr)
{
    struct test *new_fresh = (struct test *)malloc(sizeof(struct test));

    some_ptr = new_fresh;

    int some_new_data = 20;

    new_fresh -> data = some_new_data;
    new_fresh -> link = NULL;

    printf("\n\n\tInside Function");
    printf("\n\n\tData = %d\t\tAddress %x", some_ptr -> data, some_ptr);
    printf("\n\n\t____________________________________________________________");
}

And this is the output

Before Going Into Function

        Data = 10               Address 3d2488

        ____________________________________________________________

        Inside Function

        Data = 20               Address 3d2508

        ____________________________________________________________

        After Getting Out Of Function

        Data = 10               Address 3d2488

        ____________________________________________________________
Process returned 0 (0x0)   execution time : 0.000 s
Press any key to continue.

Hence, we see that the original structure variable is not changed.
So my question is how do i send the reference of the structure variable so that my output becomes

Before Going Into Function

        Data = 10               Address 3d2488

        ____________________________________________________________

        Inside Function

        Data = 20               Address 3d2508

        ____________________________________________________________

        After Getting Out Of Function

        Data = 20               Address 3d2508

        ____________________________________________________________
Process returned 0 (0x0)   execution time …
xavier666 56 Junior Poster
#define CHK_REM_2_3_5( n ) ( REM_2( n ) && REM_3( n ) && (REM_5( n ) )

@Gaiety
I think there are more divisors other than 2, 3 & 5

Please clear your concept of prime numbers

xavier666 56 Junior Poster

When they give you this just put on a disgusted face and walk away

Don't you think that they will feel that aspirant has chickened out after seeing the code

xavier666 56 Junior Poster

And try not to use gets() . It's an erratic function. To cut a long post short, look here

tux4life commented: Exactly. +6
xavier666 56 Junior Poster

Could you please help me to solve this?

Sure we could help you but at least show us what you have come up with so far

Salem commented: Indeed it is so +18
xavier666 56 Junior Poster

I would suggest Code::Blocks

xavier666 56 Junior Poster

I have tried but can't

Show us how much or whatever you have tried.
Before moving into such questions on programming, think how you would solve the problem sequencially.
Can you atleast do it without pointers, using array-index?

Assume matrices stored in column order

In C, 2D Arrays lements are stored in Row-major format. As per my knowledge, column-major is only used in Fotran and MATLAB (and this is the C forum)

xavier666 56 Junior Poster

Suppose the user wants to input a string. The length of the string is unknown. I also don't want a character array of size 1000 or what so ever. I want the size of the character array increasing by 1 byte for every character entered. Here is a sample output :

Enter String         : ABCDEFGH

Length of the String : 8

Size of the String   : 8 bytes

Some other conditions

  • The whole string will be entered at once. Not "one character entered, hit enter, then next character"
  • Terminating condition : newline

I was thinking of the algorithm. It could be something like this

int infinite_input()
{
	do
	{
		create new address for character

		if(new address == NULL)
			return 0;		            // denoting failure of function

		input character

		store character at new address

		if(previous address != NULL)
            previous address will point to new address

		echo character			        // if input does not echo

		store new address in 'previous'	// make new address as previous address

		increase size of string by 1

	}while(character != '\n');
	
	point new address to NULL

	return size of string;
}

My main problem is with the input

xavier666 56 Junior Poster

Also don't use conio.h . It is not a part of the standard C library. I guess you're compiler is quite outdated. I recommend Code::Blocks

xavier666 56 Junior Poster

Are you trying something like this?

*
	   * *
	  *   *
	 *     *
	*********

If possible, try to generalize the program for a triangle of order n (where n could be the height).
One method of solving this could be for you to first develop a program for a triangle without spaces like this one

*
	   ***
	  *****
	 *******
	*********

After that, you could modify the program to print stars only during starting and ending of loops, otherwise spaces. However, you should keep it in mind to print the entire line of stars in the last iteration for the base of the triangle.

xavier666 56 Junior Poster

>Is it possible my compiler is non ISO C standard?
Seeing as how you're compiling as C++ rather than C, I'd say that's a fair assumption.

How am I doing that (sounds silly, I know)? I mean the extension is .c but compiling as C++. My compiler automatically detects my code to be C code so I thought the compilation would be proper. Please explain where I'm going wrong.
I also saw that there is a list of compilers inside Code::Blocks from where we could choose a compiler of our liking.By default it was set to GCC compiler so i decided to stick with it.

Thanks Salem! when it works, I'll mark this thread as solved

xavier666 56 Junior Poster

> temp3 = (node *)malloc(sizeof(node));
Why are you casting the result of malloc - there is no need to do so in a correct C program.

Now this is becoming weird. After I removed type casting, I'm getting an error. Here's the premise:

Editor   - Code::Blocks 8.02
Compiler - GNU GCC Compiler

And here's what I did:

  • When I removed (node *) from temp3 = (node *)malloc(sizeof(node));
  • The error that I got is
    error: invalid conversion from `void*' to `node*'
  • I became desperate and made it temp3 = (node *)malloc(sizeof(*node)); according to the link you gave me but still it yielded no results. So i'm back where I started.

Is it possible my compiler is non ISO C standard?

xavier666 56 Junior Poster

If I ask you what does printf("Hello"); mean. You'll most probably say

It prints "Hello" on the screen

but you didn't answer my original question about its...uh..."meaning" (which it doesn't have). You only stated its purpose. So please rephrase your questions
If your questions were

What are the differences between malloc.h and alloc.h ?
What does the arrow head -> do?

then Google can sure help you.
Note - alloc.h is a non standard header file. SOURCE
Edit - Before i could submit my post, other's had already posted the solutions. Sorry for repeating!

xavier666 56 Junior Poster

Where is this thread heading to?

xavier666 56 Junior Poster

An example you can see here occasionally a = c++ + ++c; The result of that expression is undefined because (most likely) it violates the rules you cited. Consequently the result store in a will be whatever the compiler writer decided it to be.

It recently came to my light about the functioning of a +++++ b, so I've decided to share

What does a+++++b mean?

The only meaningful way to parse this is:

a ++  +  ++  b

However, the maximal munch rule requires it to be broken down as:

a ++  ++  +  b

This is syntactically invalid:
it is equivalent to:

((a++)++) +  b

But the result of a++ is not an lvalue and hence is not acceptable as an operand of ++. Thus the rules for resolving lexical ambiguity make it impossible to resolve this example in a way that is syntactically meaningful. In practice, of course, the prudent thing to do is to avoid construction like this unless you are absolutely certain what they mean. Of course, adding whitespace helps the compiler to understand the intent of the statement, but it is preferable (from a code maintenance perspective) to split this construct into more than one line:

++b;
(a++) + b;

-Taken from Shiv Dutta's article on Best Practices For Programming. (Shiv Dutta - Technical Consultant, IBM, Software Group)

Source

xavier666 56 Junior Poster

Okay, got it. Now it seem that i made a mistake. I accidentally gave the wrong snippet. That one was experimental and not fully functioning as both the head and tails need to be returned. This snippet is fully functioning but i made the head and tail variables global. But I guess that's where the 2nd structure containing the head and tail comes.
But i'm absolutely clueless about how to return both of them using structure.
Here are both the push functions

typedef struct list
{
	int data;
	struct list *forward;
	struct list *backward;
}node;

node *head;     // STORES ADRESS OF STARTING ELEMENT
node *tail;     // STORES ADRESS OF ENDING ELEMENT
node *temp1;    // CONTROL VARIABLE FOR ALL FORWARD TRAVERSAL RELATED TASK
node *temp2;    // CONTROL VARIABLE FOR ALL BACKWARD TRAVERSAL RELATED TASK
node *temp3;    // STORES NEWLY GENERATED ADDRESS FOR FORWARD LIST
node *temp4;    // STORES NEWLY GENERATED ADDRESS FOR BACKWARD LIST

void push_top( int n )
{
	temp1 = head;
	temp2 = tail;
	
    temp3 = malloc(sizeof(node));
    temp3 -> data = n;
    temp4 = malloc(sizeof(node));
    temp4 -> data = n;

	if(temp1 == NULL)   // EMPTY LIST
	{
		// 1ST TIME CREATING HEAD
		temp3 -> forward = NULL;
		head = temp3;

        // 1ST TIME CREATING TAIL
		temp4 -> backward = NULL;
		tail = temp4;
	}
	else
	{
        // ADDING NEW ELEMENT & MAKING IT THE NEW HEAD
        temp3 -> forward = head;
        head = temp3;

		// GOING TO LAST ELEMENT OF BACKWARD LIST
        while(temp2 -> backward != …
xavier666 56 Junior Poster

You need two "push" functions, one for each end of the deque.

I did that but i didn't show it. All the DEQUE functions follow this similar type of logic. I thought if this was OK, the rest of the functions should be fine

Why are you casting the result of malloc - there is no need to do so in a correct C program.

Point noted, i guess my book is a bit outdated. It specifically says to type-cast malloc 'coz of null pointer

I'll assume that logically the function is correct. Waiting for your confirmation ...

xavier666 56 Junior Poster

I was making a DEQUE program utilizing two separate lists for forward and backward traversal. But what I think I've done is ended up making two separate lists, having same data but only their order reversed, thus wasting memory :'(.
So what I want to know is this how a DEQUE push function is done(push as in pushing from top as in pushing in stack)? If I'm wrong, just tell me where to change the code :confused:

typedef struct list
{
	int data;
	struct list *forward;
	struct list *backward;
}node;

void push_top( node *head, node *tail, int n )
{
	node *temp1;    // CONTROL VARIABLE FOR ALL FORWARD TRAVERSAL RELATED TASK
	node *temp2;    // CONTROL VARIABLE FOR ALL BACKWARD TRAVERSAL RELATED TASK
	node *temp3;    // STORES NEWLY GENERATED ADDRESS FOR FORWARD LIST
	node *temp4;    // STORES NEWLY GENERATED ADDRESS FOR BACKWARD LIST	

	temp1 = head;
	temp2 = tail;

	if(temp1 == NULL)   // EMPTY LIST
	{
		// 1ST TIME CREATING HEAD
		temp3 = (node *)malloc(sizeof(node));
		temp3 -> data = n;
		temp3 -> forward = NULL;
		head = temp3;

        // 1ST TIME CREATING TAIL
		temp4 = (node *)malloc(sizeof(node));
		temp4 -> data = n;
		temp4 -> backward = NULL;
		tail = temp4;
	}
	else
	{
        // ADDING NEW ELEMENT & MAKING IT THE NEW HEAD
        temp3 = (node *)malloc(sizeof(node));
        temp3 -> data = n;
        temp3 -> forward = head;
        head = temp3;

		// GOING TO 2ND LAST ELEMENT OF BACKWARD LIST
        while(temp2 -> backward != NULL)
            temp2 = temp2 -> backward; …
xavier666 56 Junior Poster

UNICODE is a type of character, normally a character in C++ is one byte, but if UNICODE is defined, then you would be using a two byte characters (capable of holding thousands more characters to support chinese and other types of symbols

Ohh, that UNICODE! Thanks +1

I mean files with the .res extensions which allow you to internally attach files such as images or videos into the executable.

I don't know much about them (time to Google!) but can this(.res files) be done using just a C compiler? Like we do in HTML.

xavier666 56 Junior Poster

And the same compiler can produce different exe sizes depending on the flags you give it, such as DEBUG and UNICODE

What are these DEBUG and UNICODE? Can you give me an example?

And if you include 'resource files' to your application, the size will go up

By resource files, do you mean to say header files?