1
 #include <stdio.h>
 void    ft_rev_int_tab(int *tab, int size)
 {
  int *rev_tab;
  int *ptab;
  ptab = tab;
  rev_tab = tab + size ;
  while (rev_tab != ptab)
  {
     *rev_tab-- = *tab++;
     printf("%d\n",*rev_tab);
  }
  printf("%d", *rev_tab);
}
int main()
{  int array[10] = {0,1,2,3,4,5,6,7,8,9};
   ft_rev_int_tab(array, 10);
   return 0;
}

I Create a function which reverses a given array of integer.
But they show this error . If I command ./a.out| cat -e on linux, they show enter image description here

and if I command ./a.out they show enter image description here

why linux show difference Using cat -e and not using cat -e? And if I make array_size in odd number , there is no error! why this happen?

1
  • 1
    Please remove the zsh tag. Your question is unrelated to zsh. Commented Feb 26, 2021 at 10:39

1 Answer 1

2

Fixing the memory corruption

The error message means that your program crashed with an abort signal. This can be the result of a memory corruption. Memory corruptions tend to result in undefined behavior. So if your program has a memory corruption, it can happen that your program sometimes crashes and sometimes works fine. This is the case for your example. Your problem is unrelated to cat -e, it was only by luck that your program worked fine when you called it without cat -e. If you would have run your program a few more times, eventually you would have seen another crash.

In your program, the following line is causing a memory corruption:

     *rev_tab-- = *tab++;

The expression rev_tab-- is a post-decrement. A post-fix decrement decreases the variable by one and returns the old value. So for example if rev_tab is a pointer to memory location 100000 and you would run the following line:

    int* result = rev_tab--;

then after that line, rev_tab is 99999, but result received the old value of 100000.

So in your program, rev_tab initially points to rev_tab = tab + size, which is the memory location immediately after the table (i.e. the last memory location in the table is tab + size - 1. Likewise, ptab = tab; makes ptab point to the first memory location in the table. So when you do *rev_tab-- = *tab++;, even though rev_tab-- decreases rev_tab by one, meaning it now points to the last memory location in the table, the expression rev_tab-- evaluates to the previous value of rev_tab, so *rev_tab-- dereferences the pointer that points to the memory location immediately after the table. You then write the result of *tab++ to that memory location. This is a buffer overflow, which results in undefined behavior, since arbitrary memory of your process can be overwritten, resulting in corrupted memory. Your program then may or may not crash, depending on how critical the corruption is.

So to fix this problem, you should use the pre-decrement:

     *--rev_tab = *tab++;

This will fix the memory corruption, avoiding the crash.

I would advise you to enable Address Sanitization to detect such memory problems during debugging. If you use GCC or Clang, you can enable Address Sanitization by compiling with -fsanitize=address, which would give you the following output when applied to your original program:

$ gcc -fsanitize=address -g test.c
$ ./a.out 
=================================================================
==4848==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe3396f688 at pc 0x562ef80e528a bp 0x7ffe3396f5e0 sp 0x7ffe3396f5d0
WRITE of size 4 at 0x7ffe3396f688 thread T0
    #0 0x562ef80e5289 in ft_rev_int_tab test.c:10
    #1 0x562ef80e5659 in main test.c:17
    #2 0x7f6dbecf8b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #3 0x562ef80e50fd in _start (a.out+0x10fd)

Other problems

In your question you state that you want to reverse the input array. However, the code you posted does not accomplish this task. You have two pointers, one pointing to the front and one pointing to the back of the array. You then loop, incrementing the front pointer and decrementing the back pointer, until the back pointer reaches the first element. In every step of the iteration, you write the value referenced by the front pointer to the back pointer. However, you do not write the value referenced by the back pointer to the front pointer. So when the latter half of the array has been traversed, it has been overwritten with the values from the first half, and but the values from the latter half have not been written to the first half, so they are lost. Then you continue to traverse the first half, writing the values you wrote to the latter half back to the first half. So when your input array contains 0,1,2,3,4,5, your result would be 0,1,2,2,1,0. This is not the result you want.

Sign up to request clarification or add additional context in comments.

3 Comments

thank you for your help. I understood how to deal with memory in C and, I also appreciate for knowing new debugger!
Shouldn't the line but the values from the latter half have not been written to the second half, so they are lost. be changed to but the values from the latter half have not been written to the first half, so they are lost.?
@user13145713 You are right, thank you for pointing out my mistake. I have corrected my answer now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.