2

The following C program will print the shortest and longest string as t[0] and t[n-1]. However, when I run this code, it says there is a memory problem. What is wrong with my code?

The problem is the last two lines, with "strcpy".

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

void fx (char* t[], int n);

int main(void)
{
    char* t[] = {"horse", "elephant", "cat", "rabbit"};
    int n;
    n = sizeof( t )/ sizeof( t[0] );
    fx(t, n);
    printf("shortest is %s, longest is %s\n", t[0], t[n-1]);
}

void fx (char* t[], int n)
{
    char st[50], lt[50];
    strcpy(lt,t[0]);
    strcpy(st,t[0]);
    for (int i=0; i<n; i++)
    {
        if (strlen(t[i]) < strlen(st))
            strcpy(st,t[i]);
        if (strlen(t[i]) > strlen(lt))
            strcpy(lt,t[i]);
    }
    strcpy( t[0], st);
    strcpy( t[n-1], lt);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2863356
  • 241
  • 2
  • 4
  • 1
    you should use `strncpy` instead of `strcpy`. Repeatedly calling `strlen` many more tims than you need to is slow. Does your for loop really need to start at `0`, or is `1` OK? What is the error message? – Dan Oct 09 '13 at 16:19
  • Add the exact error message to your topic. – C.J. Oct 09 '13 at 16:21
  • A small rectification can be made by changing declaration as `char t[][10] = {"horse", "elephant", "cat", "rabbit"};` Read [Difference between `char* str[]` and `char str[][]` and how both stores in memory?](http://stackoverflow.com/questions/17564608/what-does-the-array-name-mean-in-case-of-array-of-char-pointers/17661444#17661444) – Grijesh Chauhan Oct 09 '13 at 16:32
  • @CJohnson, the error is "Unhandled exception at 0x1017d322 (msvcr100d.dll) in project1.exe: 0xC0000005: Access violation writing location 0x011f57b0." – user2863356 Oct 10 '13 at 15:56
  • @Dan You are right, the for loop can start from 1. The error is the error is "Unhandled exception at 0x1017d322 (msvcr100d.dll) in project1.exe: 0xC0000005: Access violation writing location 0x011f57b0." – user2863356 Oct 10 '13 at 16:16
  • @GrijeshChauhan char t[][10] works great. – user2863356 Oct 10 '13 at 16:17

3 Answers3

7

Both strcpy()s,

strcpy( t[0], st);
strcpy( t[n-1], lt);

are wrong! t[i] points to const string literals - not modifiable, which causes undefined behavior at runtime.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • In C, string literals do not have `const` type. You do have to treat them as though they do, though, because the C standard explicitly states that you're not allowed to modify them. – This isn't my real name Oct 09 '13 at 21:29
  • @ElchononEdelson Yes I know in C a string like `"HI"` is of type `char[3]` but not `const char*` actaully I wanted to write English word constant but written const. – Grijesh Chauhan Oct 10 '13 at 03:56
  • So if we continue to use char * t[], there is no way to modify t[0] and t[n-1]? Thanks. – user2863356 Oct 10 '13 at 15:57
  • @user2863356 Thing is string literals are not modifiable objects, if `t[i]` points to a string literal(as in your case) then you can't use `strcpy()` because it write on place. Yes but you have two/three ways (1) assign new string instead as `t[i] = "newstring"` (2) Suppose if `t[i]` points some array like `char s[10] = "hello"` and `t[i] = s` then you can use `strcpy(t[i], x)` where `x` points to some other string (3) As I suggested in comment to your question: "change declaration" – Grijesh Chauhan Oct 10 '13 at 17:15
  • @user2863356 I suggest you to read this answer [What does `sizeof(&array)` return?](http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499) I am sure you will find it helpful – Grijesh Chauhan Oct 10 '13 at 17:16
3
char* t[] = {"horse", "elephant", "cat", "rabbit"};

declares an array of pointers to string literals. String literals may be placed in read-only memory and cannot be modified. The final strcpy lines in fx are trying to write to read-only memory.

simonc
  • 41,632
  • 12
  • 85
  • 103
0

When you do

char *ptr = "string";

And after that if you do

ptr[0]='S';

This is going to give you error. It will compile though. Reason being, "string" is placed in the data segment or text part of the memory and is constant. This makes ptr, pointer to constant string, hence modification is not allowed.

Similarly here, all the pointers to string, i.e horse, elephant etc are constants and should not be changed.

Kraken
  • 23,393
  • 37
  • 102
  • 162