C:运行程序时出现内存错误

时间:2015-12-14 18:20:14

标签: c out-of-memory

我正在尝试编写一个接受字符串的程序(这些是给定的),然后根据它们的长度将它们存储在另一个数组中。在此之后,程序打印出具有该长度的单词的数量。我尝试使用以下代码创建它:

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

void *repeatStr(char *str, int count); 

int main() {

char arr[8][128] = { "Hallo", "Stewardess", "wat", "een", "fijne", "vlucht" };  
int groottes[11] = { 0,0,0,0,0,0,0,0,0,0,0};

    for (size_t i = 0; i <= strlen(arr); i++)   {
        char *word =  arr[i] ;      
        int grootte = strlen(word);
        groottes[grootte] += 1; 
    }

    for (size_t i = 0; i < strlen(arr); i++)    {
        char ret;
        int grt = groottes[i];
        ret = repeatStr('*', grt);
        printf("%d: %s", i + 1, ret);   
     }
}


void *repeatStr(char *str, int count) {     
    if (count == 0) return "";
    char *ret = malloc(strlen(str) * count + count);
    if (ret == NULL) return NULL;
    strcpy(ret, str);
    while (--count > 0) {
    strcat(ret, str);   
  }     
  return ret; 
}

我得到的错误是:

  

Oefening.exe中的0x0FD53B8D(ucrtbased.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000061。

3 个答案:

答案 0 :(得分:1)

鉴于此声明:

char arr[8][128] = { "Hallo", "Stewardess", "wat", "een", "fijne", "vlucht" };  

这两个循环非常不正确:

for (size_t i = 0; i <= strlen(arr); i++)   {
    /* ... */
}

注意编译器警告,如果需要,请将其打开。编译器应警告您,在strlen(arr)中,您传递的指针strlen()与其参数类型不兼容。具体来说,您传递的是char (*)[128](指向128个字符的数组的指针),而strlen()期望可能 - const char *

如果您想要arr(8)中的元素数量,那就是@NadavL建议的内容:sizeof(arr) / sizeof(arr[0])。假设您有8个元素的空间,但只有6个元素的初始化器,我想你真正想要的是

for (size_t i = 0; (i < sizeof(arr) / sizeof(arr[0])) && arr[i][0]; i++)   {
    /* ... */
}

确保i不超过数组绑定,但如果在数组用完之前用完了单词,则会停止迭代。后者是不可能的,所以没有必要检查它,如果你允许C为你选择数组大小,通过声明它,而不是:

char arr[][128] = { "Hallo", "Stewardess", "wat", "een", "fijne", "vlucht" };

答案 1 :(得分:1)

首先

char arr[8][128] = { ... };

可以更改为:

char arr[][128] = { ... };  

编译器可以查看您需要多少元素,因此当您省略第一个大小时,它会分配足够的元素。在你的情况下,你为8个字符串分配空间,而你只是初始化其中的6个字符串,这可能会导致以后出现问题。

在前两个循环中,您要检查以下条件:

i < sizeof(arr)/sizeof(arr[0])

数组是零索引的,因此如果您的数组包含n个元素,则只能访问以下元素:

arr[0], arr[1], ... , arr[n-1]

sizeof(arr)arr占用的总内存。如果您想要arr中的数组数量,则必须将其除以其元素的大小,因此sizeof(arr[0])

您拨打repeatStr的方式也存在问题 它需要一个字符串,所以我假设你想用它来调用它:

ret = repeatStr(arr[i], grt);

其中ret的定义如下:

char *ret;

因为它是一个字符串。

答案 2 :(得分:0)

在第一个循环中,您似乎想要遍历数组中的单词。

但不是这样做,你将要重复8 * 128次,因为sizeof(arr)将返回8 * 128(你分配128个字节8次 - 每个字一个)。

您真正想要使用的是:

    for (size_t i = 0; i <= (sizeof(arr)/sizeof(arr[0])); i++)

这将在您的数组中生成正确数量的单词条目。

此外,您还可以使用:

char ret;
ret = repeatStr("*", grt);

但是repeatStr返回一个char ,然后你将'ret'视为char ,即使在函数上下文中它只是一个常规字符。

更改为:

char *ret;
ret = repeatStr("*", grt);

它应该在没有内存违规的情况下编译和执行。