当我尝试在 C 中动态分配字符串数组时出现的问题

Problems when i try to dynamically allocate an array of strings in C

提问人:elmarti 提问时间:2/8/2023 最后编辑:Vlad from Moscowelmarti 更新时间:2/8/2023 访问量:65

问:

我试图弄清楚我的代码出了什么问题。编译时,没有错误或警告,只是分段错误。

有人可以告诉我我做错了什么吗?

#include "funciones.h"
#define FILAS 5 
#define COLUMNAS 3
#define VALOR 2

int main(void)
{
    int estado;
    int **matriz = NULL;

    estado = generar_matriz(FILAS,COLUMNAS, 2, matriz);

    if(estado == OK)
    {
        printf("matriz creada exitosamente \n");
    }
    else
    printf("error en el creado de la matriz \n");
        
return 0;
}

#ifndef FUNCIONES_H_
#define FUNCIONES_H_

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

#define ERROR -1
#define OK 0

int generar_matriz(int filas, int columnas, int valor, int** matriz);


#endif 

#include "funciones.h"

int generar_matriz(int filas, int columnas, int valor, int** matriz)
{
    int estado = OK,i,j;
    
    if(filas != 0 && columnas != 0)
    {
        matriz = (int**)malloc(sizeof(int*)*filas);
        
        if(matriz != NULL)
        {
            for(i = 0;i<filas;i++)
            {
                matriz[i] = (int*)malloc(sizeof(int)*columnas);
            
                if(matriz[i] == NULL)
                estado = ERROR;

                else
                {
                   for(j = 0;j<columnas;j++)
                    *(matriz[j]) = valor;
                }
            }   
        }
        else
        estado = ERROR;

    }
    else
    estado = ERROR;

    return estado;  
}

`

我认为逻辑很清楚。第一个 malloc 调用是分配一个 int 指针数组,然后我使用 for 函数请求内存并用函数接收的数字填充每个 4 个字节。我也会接受更好的代码实践和提示。谢谢。

C 引用 动态内存分配 按值传递 函数定义

评论

0赞 chux - Reinstate Monica 2/8/2023
使用 时,传入的值不会被使用,也不会更改指向的原始数据。这是故意的吗?int generar_matriz(int filas, int columnas, int valor, int** matriz)matrizmatriz
0赞 CristiFati 2/8/2023
有点相似:[SO]:使用最近邻(@CristiFati的答案)放大图像

答:

0赞 0___________ 2/8/2023 #1

它绝对不是字符串数组。

错误在这里:

*(matriz[j]) = valor;

它应该是:

 matriz[i][j] = valor;

您在这里遇到的另一个问题是,您使用了 的本地副本,并且被调用者传递的对象没有被修改。matrix

言论。

  1. 不要投射 malloc 的结果。如果代码没有编译,则您使用了错误的编译器(C++ 编译器)
  2. 使用对象而不是 's 中的类型。sizeof
1赞 Vlad from Moscow 2/8/2023 #2

您没有分配字符串数组。您正在尝试分配整数数组。

声明如下的函数generar_matriz

int generar_matriz(int filas, int columnas, int valor, int** matriz);

接受在 Main 中声明的指针 by 值matriz

estado = generar_matriz(FILAS,COLUMNAS, 2, matriz);

也就是说,该函数处理原始指针 Matriz 值的副本。更改副本不会更改原始指针。它保持不变。

如果要保留函数定义的方法,则需要通过引用传递指向函数的指针。这意味着该函数应该像这样声明

int generar_matriz(int filas, int columnas, int valor, int*** matriz);

并称

estado = generar_matriz(FILAS,COLUMNAS, 2, &matriz);

在函数中,这些for循环中还有一个问题

        for(i = 0;i<filas;i++)
        {
            matriz[i] = (int*)malloc(sizeof(int)*columnas);
        
            if(matriz[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
                *(matriz[j]) = valor;
                ^^^^^^^^^^^^^^^^^^^^^ 
            }
        }   

相反,你需要写

        for(i = 0;i<filas;i++)
        {
            matriz[i] = (int*)malloc(sizeof(int)*columnas);
        
            if(matriz[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
               matriz[i][j] = valor;
            }
        }   

但更准确地说,如果最后一个函数参数的类型为 int ***,因为它是必需的,那么循环将如下所示

        for(i = 0;i<filas;i++)
        {
            ( *matriz )[i] = (int*)malloc(sizeof(int)*columnas);
        
            if( ( *matriz )[i] == NULL)
            estado = ERROR;

            else
            {
               for(j = 0;j<columnas;j++)
                ( *matriz )[i][j] = valor;
            }
        }   

相应地,这句话

matriz = (int**)malloc(sizeof(int*)*filas);

必须像这样重写

*matriz = (int**)malloc(sizeof(int*)*filas);

你不能改变函数声明,那么你应该实现函数,这样它就会动态分配一个一维数组,你需要自己访问模拟 tw 维数组的数组元素。

例如

int generar_matriz(int filas, int columnas, int valor, int** matriz)
{
    int estado = OK,i,j;
    
    if ( filas > 0 && columnas > 0 )
    {
        *matriz = malloc( sizeof( int ) * filas * columnas );
        
        if ( *matriz != NULL)
        {
            for ( i = 0;i < filas; i++ )
            {
                for ( j = 0; j < columnas; j++ )
                    ( *matriz )[columnas * i +j] = valor;
                }
            }   
        }
        else
        estado = ERROR;
    }
    else
    estado = ERROR;

    return estado;  
}

因此,指针基本上将声明为matriz

int *matriz;

并传递给函数,如

estado = generar_matriz(FILAS,COLUMNAS, 2, &matriz);

评论

0赞 elmarti 2/8/2023
我现在看到了问题,但是有什么方法可以满足我试图对我提出的函数原型所做的事情吗?那是因为我试图练习的练习给了我一个函数的原型。
0赞 Vlad from Moscow 2/8/2023
@elmarti 你可以分配一个一维数组,如 *matriz = malloc( filas * columnas * sizeof( int ) );相应地,main 中的指针应该像 int *matriz 一样声明;并再次传递给函数,如表达式 &matriz