0

A homework assignment for an introductory C++ course.

The task is to search a two dimensional array for two numbers adding up to a given number 'search_sum.' Enter all found addends as {startRow,startColumn,endRow,endColumn} in the array 'summations,' then return the array 'summations'.

The line with summations[*sums_found] = new size_t[kIndices_size]; in the if statement was written by the instructor, as well as the comment. I am under the impression that this allocates a new space in memory where data can be assigned to and stored, so, in the next line of code, I attempted to take the column and row variables from the for loop and place them in the newly allocated memory as such. summations[*sums_found]={startRow, column, endRow, column}; This threw a 'too many assignments' and 'segmentation fault' error.

I assumed you just could not do it this way, and data must be added to a 2D array in another fashion. I removed the faulty assignment code and ran the code as shown below through a debugger, just out of curiosity. The error thrown was once again a Segmentation Fault.

// Parameters:
//  - matrix: a two-dimension integer array
//  - matrix_size: a two-element size_t array storing sizes of matrix
//  - search_sum: the integer value for which the function seeks sums
//  - sums_found: an OUTPUT PARAMETER pointing to a size_t
//
const size_t** FindSum(const int** matrix,
                       const size_t* matrix_size,
                       int search_sum,
                       size_t* sums_found) {
  *sums_found = 0;  // init sums found to 0

  size_t summations_size = 2;  // start assuming no more than 2 summations
  // build structure to hold all found summations
  size_t** summations = new size_t*[summations_size];

  switch (search_sum)
  {
  case -92:{ //column search 
    
    for(size_t column = 0; column < matrix_size[1]; column++){
        for(size_t startRow = 0; startRow < matrix_size[0]; startRow++){
            for(size_t endRow = 0; endRow < matrix_size[0]; endRow++){
              int j = matrix[startRow][column];
              int k = matrix[endRow][column];
              int sum = j + k;
              if(sum = search_sum){
                  summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found
                  *sums_found++; 
              }
            }
        }
      }
  }
    
    break;
  case 60:{ //row search
    for(size_t row = 0; row < matrix_size[0]; row++){
        for(size_t startColumn = 0; startColumn < matrix_size[1]; startColumn++){
            for(size_t endColumn = 0; endColumn < matrix_size[1]; endColumn++){
              int j = matrix[row][startColumn];
              int k = matrix[row][endColumn];
              int sum = j + k;
              if(sum = search_sum){
                  summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found
                    *sums_found++; 
              }
            }
        }
      }
  }
  break;
  case 1203:{ //desc/ascending diagonal

  }
  break;
  case 412:{ //single entry 

  }
  break;
  
  default:{ //large array

  }
    break;
  }
       
  return const_cast<const size_t**>(summations);
}

I did not know what this was, so I researched the error and found that you are not allowed to perform a read/write action on read-only code, which makes sense. What I do not understand is what exactly makes this code read-only, when it seems like its function is to assign a new space for data to be assigned to, which (to me), sounds like a 'write-like' action? I more than likely am misunderstanding the full scope of the codes function, and I am further confused with as to how I should go about assigning the data to the summations array.

Also, this is a university course taught by a grad student who is (seemingly) less than well versed in c++. It is a very 'teach yourself' type class. I understand that this assignment is an exercise on pointers and references, but it feels like I am very poorly equipped to solve a problem like this, and I am unsure what exactly to research and study independently to improve my knowledge of this particular topic. Please, if you can tell what it is I am struggling with just by looking at the code I've written, let me know what I should prioritize my studying on.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    `return const_cast(summations);` -- Remove the cast. What compiler error do you get? If you get an error, understand what it is telling you. – PaulMcKenzie Oct 14 '22 at 20:46
  • Also, an introduction to C++ would be better served if you were taught `std::vector` instead of `new[]` and `delete[]`. Using `new[]/delete[]` this way in modern C++ is frowned upon. Also, what is `kIndices_size`? I don't see it declared or defined anywhere. – PaulMcKenzie Oct 14 '22 at 20:49
  • `const_cast` has an extremely small surface area where using it is correct and not merely hiding a compiler error that exists to prevent a logic error at runtime. In general when casting be careful that you are not simply trading a problem you know about for one you don't. – user4581301 Oct 14 '22 at 21:02
  • Paul's right. Your reading materials seem to be teaching C rather than C++. This can lead to a bumpy transition into the workforce. I recommend getting [one of the introductory books listed here](https://stackoverflow.com/q/388242/4581301) to serve as back-up. – user4581301 Oct 14 '22 at 21:04
  • Suggestion: Rather than one large `switch` statement containing nested logic where there will be dozens of paths through the code that need to be tested, consider implementing each case in a function and calling the functions from inside the `switch`. Now each case can be easily tested on its own, and when you know they all work individually all you typically need to test in the `switch` is whether they get called or not. – user4581301 Oct 14 '22 at 21:23
  • The code does not seem to resize `summations`'s array when more summations are found. This is likely the source of the fault. You cannot `summations[*sums_found]` until after you know there is sufficient space for a `*sums_found] element. Typically this requires you to create a new, larger array copy the items in the existing array to the new array then free the existing array and point `summations` at the new array. I strongly recommend using `vector` instead, but if you cannot, make a new class that does the grunt work so you can isolate it from the rest of the code. – user4581301 Oct 14 '22 at 21:30
  • @PaulMcKenzie the return statement was also written by my instructor. Removing the cast seems like it would make the function not return at all since the return type should be a const? We very briefly touched on const casting in lecture, I will research it to better understand it. – David Wamai Oct 14 '22 at 21:31
  • @user4581301 Thank you for the suggestion, I will check those out and compare them with what is being taught in class. – David Wamai Oct 14 '22 at 21:33
  • A non-`const` value can be viewed through a `const` lens without explicit conversion. The real danger is when you cast away `const` from a value that you should not or must not alter. – user4581301 Oct 14 '22 at 21:36
  • `The code does not seem to resize summations's array when more summations are found. This is likely the source of the fault. You cannot summations[*sums_found] until after you know there is sufficient space for a *sums_found] element.` So since *sums_found is initialized as 0, the line in the if statement is read as "summations of size 0 is a new array of size kIndices_size" rather than "summations at index 0 is a new array of size kIndices_size?" This would make more sense, but i'd like to clarify if that is actually the case or if Im misunderstanding. @user4581301 – David Wamai Oct 14 '22 at 21:38
  • The point I'm trying to make is `size_t** summations = new size_t*[summations_size];` points `summations` at an array of size 2. If `*sums_found` is incremented to 2 or higher, array indexes are valid from zero to size -1, `summations[*sums_found]` accesses memory out of bounds and the program breaks. It may not visibly break right away, but the program no longer plays by the rules. You can't be sure exactly what was read or written over, so you can't be sure what the program's result will be. You got lucky and the program crashed, but it could have kept going and given the wrong answer. – user4581301 Oct 14 '22 at 21:45
  • Or even the right answer. The thing is you can't know. We call this Undefined Behaviour because what will happen is not guaranteed by the rules of the language. – user4581301 Oct 14 '22 at 21:46
  • @user4581301 I think I understand. I will have to go back and review pointers and references since I did not catch that initially. Thank you for the clarification. – David Wamai Oct 14 '22 at 21:50

0 Answers0