C - Off by one error, but no segmentation fault?

跟風遠走 提交于 2020-03-05 07:55:49

问题


I recently wrote this code in C:

#include <stdio.h>

#define N_ROWS 100


int main() {

  char *inputFileName = "triangle_data.txt";
  FILE *inputFile = fopen(inputFileName, "r");

  if (inputFile == NULL) {
    printf("ERROR: Failed to open \"%s\".\n", inputFileName);
    return -1;
  }

  int triangle[(N_ROWS*(N_ROWS+1))/2 - 1];
  size_t size = sizeof(triangle)/sizeof(int);
  size_t index;


  for (index = 0; !feof(inputFile); ++index) {
    fscanf(inputFile, "%d", &triangle[index]);
  }

  return 1;
}

and was expecting a Segmentation Fault, since N_ROWS*(N_ROWS+1))/2 is just enough space to hold the data in the file, but as you can see I made the array one element smaller. Somehow this doesn't trigger a segmentation fault. It does if I replace the body of the for-loop with:

int tmp;
fscanf(inputFile, "%d", &tmp);
triangle[index] = tmp;

What is happening here. If I make the array three elements to small it still doesn't trigger a segmentation fault. Five elements to small trigger one. I'm sure there is enough data in the file.

As a test I printed the array afterwards and if I choose a smaller array there were elements missing.

What is happening here?

PS: Compiled with clang on a OS X.


回答1:


What is happening here?

Your program invokes undefined behavior as you are writing outside your array object. Undefined behavior in C is undefined, your program can work today and crash all the other days or even print Shakespeare complete works.




回答2:


A segmentation fault doesn't mean that you accessed an array out of bounds, it means that you've accessed a virtual memory address that isn't mapped. Often accessing an array out of bounds will cause this, but just because you aren't seeing a segfault it doesn't mean that all of your memory accesses are valid.

As to why you're seeing the different behavior, it's hard to say and it isn't necessarily a worthwhile use of time to try justifying different results when the results are specified as undefined. If you're really curious about what's going on you could look at the assembly generated by the two versions of your code (use the --save-temps argument to clang).




回答3:


The behaviour of your program (accessing an array element out of bounds) is undefined.

There is no particular requirement that undefined behaviour result in a segmentation fault, or any other observable error condition.

Undefined behaviour means - literally - that the C standard does not impose any restrictions on what is allowed to occur. That means anything can happen, including appearing to work correctly, or working in one circumstance but not another.

The trick is not to worry about the particular potential causes of segmentation faults (or any other error condition that any instance of undefined behaviour might trigger). It is to ensure the program has well-defined behaviour, so such symptoms are guaranteed not to occur.



来源:https://stackoverflow.com/questions/34521292/c-off-by-one-error-but-no-segmentation-fault

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!